【问题标题】:AngularJS controllers and "use strict"AngularJS 控制器和“使用严格”
【发布时间】:2012-10-09 02:04:55
【问题描述】:

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

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

当我删除“使用严格”的功能形式时,控制器加载正常。

控制器:

(function () {
    "use strict";

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

}());

有人知道这里发生了什么吗?

【问题讨论】:

    标签: angularjs jshint use-strict


    【解决方案1】:

    首先,我想说 pkozlowski 真的很了解他在 Angular 的工作,但这实际上并不是 Angular 的问题,而是关闭的问题。

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

    1. 在自己的通过 Module.controller() 注册的控制器注册表中
    2. 全局变量(或全局函数声明)中

    问题在于“use strict”闭包中的所有内容都不是全局的。它被封装并私有化在包含它的匿名函数中。

    (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 方法显式注册它们。

    【讨论】:

      【解决方案2】:

      我猜 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 服务。

      【讨论】:

      • 知道如何使用“use strict”声明自动执行将所有角度代码包装在 IIFE 中的任务吗? (我正在使用咕噜声)
      • @FlorianF 我个人在 WebStorm 中使用 LiveTemplates
      • jshint 警告并非完全是为了防止全局变量,而是为了防止类似的全局“使用严格”问题。如果您将文件连接在一起(一个常见的构建步骤),顶级“使用严格”将适用于所有后续文件(即使它们不是为了符合 jshint 而编写的)。函数形式将 jshint 限制为仅适用于该函数。跨度>
      【解决方案3】:

      如果您的 Angular 模块已经加载到其他地方,那么 @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') 检索现有模块。

      【讨论】:

        【解决方案4】:

        你有没有尝试在 (function() 之外和之前写 'use strict'

        "use strict"; // <-- add it here
        (function () {
            //"use strict"; <-- remove from here
        
            function webAddressController($scope, $rootScope, web_address_service) {
                 // Do things
            }
        
        }());
        

        我的回答是基于我看到的Yeoman生成的文件

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-09-29
          • 2015-08-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多