AngularJS控制器和“使用严格”

时间:2012-10-18 14:56:49

标签: angularjs jshint use-strict

我最近开始使用JSHint,它要求我使用“use strict”的函数形式。从那以后,AngularJS抛出一个错误:

“错误:参数'webAddressController'不是函数,未定义”

当我删除“use strict”的函数形式时,控制器加载正常。

控制器:

(function () {
    "use strict";

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

}());

有没有人对这里发生的事情有任何见解?

3 个答案:

答案 0 :(得分:44)

首先,我想声明pkozlowski真的知道他在Angular的东西,但这实际上不是一个Angular问题,因为它是关闭的问题。

Angular正在两个地方寻找控制器:

  1. 在其自己的通过Module.controller()
  2. 注册的控制器注册表中
  3. 全局变量(或全局函数声明)
  4. 问题是你的闭包中“使用严格”的所有内容都不是全局的。它被包含并在包含它的匿名函数中私有化。

    (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;
      })();
    

    在一天结束时,您可以在任何功能内部使用“use strict”,如果您愿意,可以在文件级别。 “使用严格”本身并不会破坏任何东西。正如您所看到的,有一千种注册控制器的方法。最好的选择可能就是根据建议用.controller方法显式注册它们。

答案 1 :(得分:14)

我想JSHint试图告诉你这里是为了避免全局变量(这显然是一个非常好的做法!)。

AngularJS对于解决同一问题(即避免全局变量)的看法略有不同,并允许您在模块中定义控制器(使用全局angular命名空间)。您可以使用以下模块重写您的示例:

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

以下是jsFiddle在实践中说明这一点:http://jsfiddle.net/t3vBE/1/

使用此方法,您不会使用控制器构造函数来污染全局命名空间。

如果要使用严格模式,则需要更改JSHint配置以允许angular全局变量。或者,您也可以将整个代码(再次使用模块)包装到一个可以执行的函数中:

(function () {
    "use strict";

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

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

}());​

这是jsFiddle:http://jsfiddle.net/t3vBE/4/

对我来说,只有你想要定义纯JavaScript,“帮助”函数才有意义,否则我会依赖AngularJS服务。

答案 2 :(得分:4)

如果您的角度模块已经加载到其他地方,那么@pkzolowski正在做的另一种方法是:

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

基于此处的评论: angularjs defining services for the same module in different files

  

注意使用angular.module('myModule',[])将创建模块myModule并覆盖任何名为myModule的现有模块。使用angular.module('myModule')来检索现有模块。