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


93

私はアプリケーションを構築するために山形シードテンプレートを使用しています。最初に、すべてのJavaScriptコードを単一のファイルに入れましたmain.js。このファイルには、モジュール宣言、コントローラー、ディレクティブ、フィルター、サービスが含まれています。アプリケーションはこのように正常に動作しますが、アプリケーションがより複雑になるため、スケーラビリティとメンテナンス性が心配です。Angular-seedテンプレートにはこれらのファイルごとに個別のファイルがあることに気付いたので、コードを単一のmain.jsファイルからこの質問のタイトルに記載されている他の各ファイルに配布しようとしましたapp/jsが、angularのディレクトリで見つかりました-シードテンプレート。

私の質問は、アプリケーションを機能させるために依存関係をどのように管理するのですか?既存の文書が見つかりました。ここでは例の各番組に、単一の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
}

依存関係をどのように管理しますか?

前もって感謝します。


2
これに関するいくつかの記事があります。たとえば、briantford.com/blog/huuuuuge-angular-apps.htmlや、yeomanなどのいくつかのプロジェクト。これには2つの方法があります。いくつかの記事で提案されているように、コンポーネントをレイヤー(角度シードなど)または機能で分離する方法です。
Eduard Gamonal 2013年

angular.module( 'myApp.service1'、[])などのモジュールを宣言する場合、[]に依存関係を追加する必要があると思いますたとえば、angular.module( 'myApp.service1'、['myApp.service2'、 'myApp .service2 '])。。私はAngularJSにかなり慣れていないので、間違っているかもしれません。問題が解決しない場合はお知らせください。回答を投稿します。
ダニーVarod 2013年

その行はどこに挿入すべきですか?angular.module('myApp.services', ['myApp.services']);運が悪いのでapp.jsに入れました。
ChrisDevo 2013年

@ChrisDevo 1.コメントに返信するときは、コメントを必ず「@」とユーザー名(スペースなし)で始めてください。そうすると、ユーザーに通知が届きます。2. myApp.servicesは、それ自体ではなく、他のモジュールに依存している必要がありますangular.module('myApp.services', ['myApp.server', 'myApp.somethingElse'])
ダニーVarod 2013年

@DannyVarod、以前のコメントを編集しましたか?angular.module('myApp.service1', ['myApp.service1', 'myApp.service2'])元々読んだ。それ以外の場合は、独自の依存関係としてmyApp.servicesを含めませんでした。
ChrisDevo 2013年

回答:


108

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

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

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

これは、アプリケーションモジュールへの割り当て(割り当てが正しいかどうかは不明)のようになります。

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

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

そのため、角括弧付きの旧バージョンは、通常、app.jsまたはで1回だけ使用する必要がありますmain.js。他のすべての関連ファイル(コントローラー、ディレクティブ、フィルターなど)は、角かっこなしの後者のバージョンを使用する必要があります。

私はそれが理にかなっていると思います。乾杯!


9
この問題の解決策を見つけました。必要なモジュールは1つだけのようですmyApp。私のapp.jsファイルで、そのvarを作成しました。var myApp = angular.module('myApp', []);他のすべてのファイルでこのvarを単に参照しました(たとえば、myApp.filter('myFilter', function(MyService) { /* filter code */ });htmlのスクリプトタグにファイル名を追加している限り、他のファイルを宣言する必要はありませんでした)依存関係。山形種子のプロジェクトテンプレートは、この点でかなり混乱しています
ChrisDevo 2013年

1
今、私は本当に混乱しています。私は戻ってグローバル変数を削除したmyAppので、これは今では匿名モジュールになっていapp.jsますangular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers']);。他のすべてのファイルでも、このような匿名モジュールを宣言しましたangular.module('myApp.filter', []).filter('myFilter', function(MyService) { /* filter code */ });。私のアプリもこのように動作します。私はコード履歴を調べましたが、これが機能しなかったときとどこが違うのかわかりません。
ChrisDevo 2013年

4
これがうまくいくことを約束します。Angular Appsの開発に毎日使用しています。繰り返しangular.module('myApp', []);ますが、メインのjsファイルで(角括弧に注意して)を1つ宣言しています。その後、他のすべてのファイルは、angular.module('myApp').controlleror .directive構文を使用してモジュールを参照します。
Justin L.

5
エラーは、AngularがmyApp.controller、myApp.filtersと呼ばれるモジュールを探しているために発生しますが、これらはモジュールではなく、myAppと呼ばれる1つのモジュールを拡張するコンポーネントです。すべてのmyApp.whateverをモジュールの依存関係から削除すると、すべてが機能するはずです。ただ、空の角括弧を保つ(あなたは、他の真の角度のモジュールを含むされていない限り、例えばngCookiesngResource)あなたのメインアプリモジュール宣言するとき:angular.module('myApp', []);
ジャスティン・L.

1
あ、そう。これらをアプリモジュールの依存関係として配置すると、それらを見つける必要があるためエラーになります。それらを角括弧から外すと、自由にロードでき、アプリは気にしません。ngResource間違いなく、モジュール宣言の括弧に入れるものの1つです。私の回答が役に立った場合は、投票して承認していただければ幸いです。
ジャスティンL.

12

アプリケーション(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つの呼び出しに組み合わせることができます。

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

重要な部分は、再定義すべきではないということですangular.module('myApp')。これにより、コントローラーをインスタンス化するときに上書きされる可能性があります。


1
私はこのアプローチが好きで、それを使用して階層構造を作成できます(たとえば、コントローラーにサービスまたはフィルターが必要だとします)。注:サブコントローラー(コントローラーのフィルターなど)が注入されると、注入を再宣言せずに、上記のすべての親(ツリーとして視覚化している場合)でも使用できることを確認しました。子を変更して親で使用している場合は、忘れてください。また、1つのファイルに複数のモジュール(名前空間)を入れないでください。また、複数のファイルで同じ名前空間を使用しないでください。
ゲーリー

2つのコントローラーファイルまたは2つのサービスファイルがある場合はどうなりますか?インスタンス化は各単一ファイルで発生しますか?
Avinash Raj

3

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

app.js

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

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

これでエラーは解消されますが、コメントの1つに記載されているEduard Gamonalの記事を読んでおく必要があります。


Torstenに感謝しますが、その記事を読んでangular.module('myApp.services', []);app.jsファイルにその行を追加しました。どちらも実際には私の問題に対処していません。
ChrisDevo 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.