web-dev-qa-db-ja.com

AngularJSシード:JavaScriptを個別のファイル(app.js、controllers.js、directives.js、filters.js、services.js)に配置する

angular-seed テンプレートを使用して、アプリケーションを構築しています。最初に、すべてのJavaScriptコードを単一のファイルmain.jsに配置しました。このファイルには、モジュール宣言、コントローラー、ディレクティブ、フィルター、およびサービスが含まれていました。アプリケーションはこのように正常に動作しますが、アプリケーションがより複雑になるため、スケーラビリティと保守性が心配です。角度シードテンプレートにはこれらのそれぞれに個別のファイルがあることに気づいたので、単一のmain.jsファイルのコードを、この質問のタイトルで言及され、 angular-seed テンプレートのapp/jsディレクトリ。

私の質問は、アプリケーションを動作させるために依存関係をどのように管理すればよいですか? here で見つかった既存のドキュメントは、この例では明確ではありません。これは、指定された各例が1つのJavaScriptソースファイルを示しているためです。

私が持っているものの例は次のとおりです。

app.js

angular.module('myApp', 
    ['myApp.filters',
     'myApp.services',
     'myApp.controllers']);

controllers.js

angular.module('myApp.controllers', []).
    controller('AppCtrl', [function ($scope, $http, $filter, MyService) {

        $scope.myService = MyService; // found in services.js

        // other functions...
    }
]);

filters.js

angular.module('myApp.filters', []).
    filter('myFilter', [function (MyService) {
        return function(value) {
            if (MyService.data) { // test to ensure service is loaded
                for (var i = 0; i < MyService.data.length; i++) {
                    // code to return appropriate value from MyService
                }
            }
        }
    }]
);

services.js

angular.module('myApp.services', []).
    factory('MyService', function($http) {
        var MyService = {};
        $http.get('resources/data.json').success(function(response) {
            MyService.data = response;
        });
        return MyService;
    }
);

main.js

/* This is the single file I want to separate into the others */
var myApp = angular.module('myApp'), []);

myApp.factory('MyService', function($http) {
    // same code as in services.js
}

myApp.filter('myFilter', function(MyService) {
    // same code as in filters.js
}

function AppCtrl ($scope, $http, $filter, MyService) {
    // same code as in app.js
}

依存関係を管理するにはどうすればよいですか?

前もって感謝します。

93
ChrisDevo

問題は、すべての個別のファイルでアプリケーションモジュールを「再宣言」することにより発生します。

これは、アプリモジュール宣言(宣言が正しい用語であるかどうかはわかりません)は次のようになります。

angular.module('myApp', []).controller( //...

これは、アプリケーションモジュールへの割り当て(割り当てが正しい用語であるかどうかはわかりません)は次のようになります。

angular.module('myApp').controller( //...

角括弧がないことに注意してください。

したがって、前のバージョンであるwithは角括弧で、通常はapp.jsまたはmain.jsで一度だけ使用する必要があります。他のすべての関連ファイル— コントローラー、ディレクティブ、フィルター…— —後者のバージョンを使用する必要がありますwithout角括弧。

それが理にかなっていることを願っています。乾杯!

108
Justin L.

アプリケーションのさまざまな部分(filters, services, controllers)をさまざまな物理ファイルに配置する場合は、次の2つのことを行う必要があります。

  1. app.jsまたは各ファイルでこれらの名前空間を宣言します(より良い用語がないため)。
  2. 各ファイルのそれらの名前空間を参照してください。

したがって、app.jsは次のようになります。

angular.module('myApp', ['external-dependency-1', 'myApp.services', 'myApp.controllers'])
.run(function() {
   //...

})
.config(function() {
  //...
});

そして、個々のファイルで:

services.js

angular.module('myApp.services', []); //instantiates
angular.module('myApp.services') //gets
.factory('MyService', function() { 
  return {};
});

controllers.js

angular.module('myApp.controllers', []); //instantiates
angular.module('myApp.controllers')      //gets
.controller('MyCtrl', function($scope) {
  //snip...
})
.controller('AccountCtrl', function($scope) {
  //snip...
});

これらすべてを1つの呼び出しに結合できます。

angular.module('myApp.controllers', []) 
.controller('MyCtrl', function($scope) {
 //snip...
});    

重要な部分は、angular.module('myApp');を再定義しないことです。コントローラをインスタンス化するときに上書きされる可能性がありますが、おそらく必要なものではありません。

11
George Stocker

myApp.servicesをまだ定義していないため、エラーが発生します。これまでに行ったことは、すべての初期定義を1つのファイルに入れてから、別のファイルで使用することです。あなたの例のように私は入れます:

app.js

angular.module('myApp.services', []);

angular.module('myApp', 
    ['myApp.services',
      ...]);

これでエラーは解消されますが、コメントの1つで言及されている記事 Eduard Gamonal を読むべきだと思います。

3