28

最近JSHintを使い始めましたが、「usestrict」という関数形式を使用する必要があります。それ以来、AngularJSはエラーをスローします:

「エラー:引数'webAddressController'は関数ではなく、未定義になりました」

「usestrict」の関数形式を削除すると、コントローラーは正常にロードされます。

コントローラ:

(function () {
    "use strict";

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

}());

ここで何が起こっているのかについて誰かが何か洞察を持っていますか?

4

4 に答える 4

44

まず、pkozlowskiがAngularでの彼のことを本当に知っていることを述べたいと思いますが、これは実際には、閉鎖の問題であるほどAngularの問題ではありません。

Angularは2つの場所でコントローラーを探しています:

  1. Module.controller()を介して登録されたコントローラーの独自のレジストリ内
  2. グローバル変数(またはグローバル関数宣言)内

問題は、「厳密に使用する」ためのクロージャー内のすべてがグローバルではないことです。それは、それを含む無名関数にまとめられ、民営化されます。

(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メソッドに明示的に登録することです。

于 2012-10-19T03:28:28.197 に答える
14

JSHintがここであなたに伝えようとしているのは、グローバル変数を避けることだと思います(これは明らかに非常に良い習慣です!)。

AngularJSは、同じ問題を解決すること(つまり、グローバル変数を回避すること)について少し異なる意見を持っており、モジュールでコントローラーを定義できます(グローバルangular名前空間を使用)。次のようなモジュールを使用して、例を書き直すことができます。

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

これを実際に説明するjsFiddleは次のとおりです。http://jsfiddle.net/t3vBE/1/

このアプローチでは、コントローラーコンストラクターでグローバル名前空間を汚染することはありません。

angularストリクトモードを使用する場合は、グローバル変数を許可するようにJSHint構成を変更する必要があります。または、コード全体を(もう一度、モジュールを使用して)すぐに実行される関数にラップすることもできます。

(function () {
    "use strict";

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

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

}());​

これがjsFiddleです:http://jsfiddle.net/t3vBE/4/

私にとってこれは、純粋なJavaScriptの「ヘルパー」関数を定義する場合にのみ意味があります。それ以外の場合は、AngularJSサービスに依存します。

于 2012-10-18T17:42:00.280 に答える
4

Angularモジュールがすでに他の場所にロードされている場合に@pkzolowskiが実行していることを実行する別の方法:

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

これは、ここからのコメントに基づいています: 異なるファイルで同じモジュールのサービスを定義するangularjs

angle.module('myModule'、[])を使用すると、モジュールmyModuleが作成され、myModuleという名前の既存のモジュールが上書きされることに注意してください。既存のモジュールを取得するには、angular.module('myModule')を使用します。

于 2014-08-01T21:30:32.707 に答える
2

(function()の前と外で'usestrict'を書いてみましたか

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

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

}());

私の答えは、ヨーマンによって生成された私が見たファイルに基づいています

于 2017-05-12T15:23:41.287 に答える