Kontrolery AngularJS i " stosuj ścisłe"

Ostatnio zacząłem używać JSHint i wymaga to ode mnie użycia funkcji "use strict". Od tego czasu AngularJS wyrzuca błąd:

"Error: Argument 'webAddressController' is not a function, got undefined "

Po usunięciu funkcji "use strict" kontroler ładuje się dobrze.

Kontroler:

(function () {
    "use strict";

    function webAddressController($scope, $rootScope, web_address_service) {
             // Do things
    }

}());
Czy ktoś wie, co się tu dzieje?
Author: Elnur Abdurrakhimov, 2012-10-18

4 answers

Po pierwsze, chcę powiedzieć, że pkozlowski naprawdę zna się na Angular, ale to nie jest tak bardzo kanciasty problem, jak to jest problem z zamknięciem.

Angular szuka kontrolerów w dwóch miejscach:

  1. we własnym rejestrze kontrolerów zarejestrowanych za pośrednictwem modułu.controller ()
  2. In a global variable (or global function declaration)

Problem polega na tym, że wszystko w Twoim zamknięciu dla "USE strict" nie jest globalne. On zawinięty i sprywatyzowany w funkcji anonimowej, która go zawiera.

(function() {
   // nothing in here is global or even public.
   // "use strict" or not.

   "use strict"; // this is mostly irrelevant.

   // this will not work, because it's wrapped and not global
   function ThisDoesntWork($scope) {
   };

   // window is the global root variable. So this works.
   window.ThisWorks = function($scope) {

   };

   // this will work, because it's explicitly registering the controller
   // presuming app is your Module variable from outside of the closure.
   app.controller('ThisIsBest', function($scope) {

   });

})();

//this works because it's global.
function ThisAlsoWorks($scope) {

}

// if you declare a global var, then set it inside
// of your closure, you're good to go too.
var ThisWillWorkToo;

(function {
    //here we're setting it again.
    ThisWillWorkToo = function($scope) {
    };
})();


// if you're really crazy you can even do this...
 var ThisWillWorkButItsWeird = (function() {
      "use strict";

       function ThisWillWorkButItsWeird($scope) {

       }

       return ThisWillWorkButItsWeird;
  })();

Pod koniec dnia możesz umieścić "use strict" wewnątrz dowolnej funkcji lub na poziomie pliku, jeśli chcesz. samo "stosowanie ścisłe" nie łamie niczego dla Ciebie. Jak widać, istnieje tysiąc sposobów rejestracji kontrolera. Najlepszym wyborem jest prawdopodobnie po prostu wyraźnie zarejestrować je w.metoda kontrolera zgodnie z sugestią.

 44
Author: Ben Lesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-15 15:03:26

Myślę, że JSHint próbuje ci powiedzieć, że należy unikać zmiennych globalnych (co jest oczywiście bardzo dobrą praktyką!).

AngularJS ma nieco inne zdanie na temat rozwiązania tego samego problemu (czyli unikania zmiennych globalnych) i pozwala definiować Kontrolery w modułach (używając globalnej przestrzeni nazw angular). Możesz przepisać swój przykład używając takich modułów:

angular.module('myApp',[]).controller('webAddressController', function($scope) {
    // Do things
});

Oto jsFiddle ilustrujące to w praktyce: http://jsfiddle.net/t3vBE/1/

Dzięki takiemu podejściu nie zanieczyszczasz globalnej przestrzeni nazw konstruktorami kontrolerów.

Jeśli chcesz używać trybu ścisłego, musisz zmienić konfigurację JSHint, aby zezwolić na zmienną globalną angular. Alternatywnie możesz również zawinąć cały kod (po raz kolejny, używając modułów) w funkcję, która jest wykonywana imediately:
(function () {
    "use strict";

angular.module('myApp',[]).controller('webAddressController', function($scope) {

    $scope.name = 'World';
    // Do things
});

}());​

Oto jsFiddle: http://jsfiddle.net/t3vBE/4/

Dla mnie to ma sens tylko wtedy, gdy chcesz zdefiniować czysty JavaScript, funkcje "pomocnicze", w przeciwnym razie polegałbym na usługach AngularJS.

 14
Author: pkozlowski.opensource,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-13 19:00:58

Inny sposób na to ,co robi @ pkzolowski, jeśli twój moduł kątowy jest już załadowany gdzie indziej:

var app = angular.module('myApp');
app.controller(...);
app.service(...);
...

Opiera się na komentarzu stąd: angularjs definiowanie usług dla tego samego modułu w różnych plikach

Uważaj na kątowe.moduł('myModule', []) utworzy moduł myModule i nadpisze dowolny istniejący moduł o nazwie myModule. Użyj kątowego.moduł ('myModule') do pobrania istniejącego modułu.

 4
Author: zeusstl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:13

Czy próbowałeś napisać 'use strict' Na zewnątrz i przed (function ()

"use strict"; // <-- add it here
(function () {
    //"use strict"; <-- remove from here

    function webAddressController($scope, $rootScope, web_address_service) {
         // Do things
    }

}());

Moja odpowiedź opiera się na plikach, które widziałem wygenerowane przez Yeoman

 2
Author: Siddhesh T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-12 15:23:41