2012-10-18 64 views
27

我最近開始使用JSHint,它要求我使用「use strict」函數形式。此後,AngularJS拋出一個錯誤:AngularJS控制器和「嚴格使用」

「錯誤:參數‘webAddressController’不是一個函數,得到了不確定的」

當我刪除「使用嚴格的」控制加載罰款的函數形式。

控制器:

(function() { 
    "use strict"; 

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

}()); 

是否有人在這裏發生了什麼任何見解?

回答

43

首先,我想說明pkozlowski真的知道他在Angular的東西,但實際上這並不像Angular問題那麼多,因爲它是關閉的問題。

角是在兩個地方尋找控制器:

    在自己通過Module.controller()
  1. 全球變量(或全局函數聲明)
註冊控制器的註冊表
  • 問題是關閉中「嚴格使用」的內容不是全局的。它在包含它的匿名函數中被封裝和私有化。

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

    在這一天結束時,你可以把「使用嚴格」的任何函數內,或者在文件級別,如果你喜歡。 「嚴格使用」本身不會破壞你的任何東西。正如你所看到的,有一千種註冊控制器的方法。根據建議,最好的選擇可能就是用.controller方法明確地註冊它們。

  • 14

    我想JSHint試圖告訴你這裏是爲了避免全局變量(這顯然是一個非常好的做法!)。對於解決相同的問題(即避免全局變量),AngularJS有不同的意見,並且允許您在模塊中定義控制器(使用全局angular名稱空間)。你可以使用這樣的模塊重寫你的榜樣:

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

    這裏是的jsfiddle說明在實踐中:http://jsfiddle.net/t3vBE/1/

    通過這種方法你是不是污染帶控制器構造全局命名空間。

    如果您想使用嚴格模式,您將需要更改JSHint配置以允許angular全局變量。另外,您還可以換你的整個代碼(再次使用模塊),其被imediatelly執行到的函數:

    (function() { 
        "use strict"; 
    
    angular.module('myApp',[]).controller('webAddressController', function($scope) { 
    
        $scope.name = 'World'; 
        // Do things 
    }); 
    
    }());​ 
    

    這裏是的jsfiddle:http://jsfiddle.net/t3vBE/4/

    對我來說,這是有道理的唯一,如果你想定義純粹的JavaScript,「幫手」功能,否則我會依賴AngularJS服務。

    +1

    任何想法如何我可以自動完成包含所有我的角碼在一個IIFE與'使用嚴格'宣言的任務? (我正在使用grunt) –

    +0

    @FlorianF我個人在WebStorm中使用LiveTemplates –

    +2

    jshint警告並不完全是爲了防止全局變量,而是爲了防止類似的全局「嚴格使用」問題。如果將文件連接在一起(通用構建步驟),頂級「use strict」將應用於所有後續文件(即使它們未被寫入以符合jshint)。函數形式僅將jshint限制爲該函數。 –

    4

    另一種方式做,如果你的角模塊已經在其他地方裝有何種@pkzolowski做:

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

    它是基於從這裏評論: angularjs defining services for the same module in different files

    Beware that using angular.module('myModule', []) will create the module myModule and overwrite any existing module named myModule. Use angular.module('myModule') to retrieve an existing module.

    1

    你試過(功能()

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

    我的答案是基於我見過的文件生成的Yeoman