個別のAngularJSコントローラーファイルを作成するには?


315

AngularJSコントローラーをすべて1つのファイル(controllers.js)に格納しています。このファイルは次のように構成されています。

angular.module('myApp.controllers', [])
  .controller('Ctrl1', ['$scope', '$http', function($scope, $http) {    
  }])
  .controller('Ctrl2', ['$scope', '$http', function($scope, $http) }
  }])

私がやりたいことは、Ctrl1とCtrl2を別々のファイルに入れることです。次に、両方のファイルをindex.htmlに含めますが、どのように構成する必要がありますか?私はこのようなことを試してみましたが、コントローラーが見つからないというエラーがWebブラウザーコンソールにスローされます。ヒントはありますか?

StackOverflowを検索したところ、同様の質問が見つかりました。ただし、この構文ではAngularの上で別のフレームワーク(CoffeeScript)を使用しているため、追跡できませんでした。


AngularJS:複数のファイルでコントローラーを作成する方法

回答:


399

ファイル1:

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

ファイル2:

angular.module('myApp.controllers').controller('Ctrl1', ['$scope', '$http', function($scope, $http){

}]);

ファイル3:

angular.module('myApp.controllers').controller('Ctrl2', ['$scope', '$http', function($scope, $http){

}]);

その順序で含めます。3つのファイルをお勧めしますので、モジュール宣言はそれ自体です。


フォルダ構造については、この件について多くの意見がありますが、この2つはかなり良いです

https://github.com/angular/angular-seed

http://briantford.com/blog/huuuuuge-angular-apps.html


1
OPがCoffeeScript構文についての混乱を示した場合、多分それを回答に使用しないのが最善でしょうか?
Andrew

3
@Andrew imho将来の助けと解決策の記録を作成することは、SOが本当の意味であり、即席の質疑応答ではありません。
Fresheyeball 2014年

2
@RuslanIsmagilovあなたappCtrlはグローバルwindow.appCtrlです。それは良い習慣ではありません。
Fresheyeball 2014年

1
@Fresheyeball、このアプローチの問題は、index.htmlでのインポートの順序が重要です。それ以外の場合、Angularはエラーを出力します。
デオキシセイア2014年

2
@hendryau、まあ私はOPに存在するモジュール名で作業していました。とはいえ、中央のアプリモジュールではなく、複数の名前空間モジュールを使用する方が組織的に優れていると考える人もいます。
Fresheyeball 2015年

177

angular.module API を最後に配列とともに使用すると、 angularに新しいモジュールを作成するように指示します。

myApp.js

// It is like saying "create a new module"
angular.module('myApp.controllers', []); // Notice the empty array at the end here

配列なしで使用すると、実際にはゲッター関数になります。コントローラーを分離するには、次のようにします。

Ctrl1.js

// It is just like saying "get this module and create a controller"
angular.module('myApp.controllers').controller('Ctrlr1', ['$scope', '$http', function($scope, $http) {}]);

Ctrl2.js

angular.module('myApp.controllers').controller('Ctrlr2', ['$scope', '$http', function($scope, $http) {}]);

JavaScriptのインポート中は、myApp.jsがAngularJSの後、コントローラー/サービスなどの前にあることを確認してください。そうしないと、angularはコントローラーを初期化できません。


依存関係はどこに書けばよいですか。var myapp = angular.module( 'demo'、['ngRoute'、 'ngCookies'、 'ui.bootstrap'、 'nvd3ChartDirectives'、 'ui-rangeSlider'、 'textAngular'、 'angularTreeview']);
vipin 2014

@vipinは入力した内容と同じですが、コントローラー、サービスなどの上にあることを確認してください。技術的には、var myapp = ...;を宣言する必要はありません。アンギュラーがそれを保存するからです。
ジミーAu

@JimmyAuページがそれを使用できるように、Ctrl1.jsとCtrl2.jsはどこに読み込まれますか?Angularの直後にmyApp.jsをロードしましたが、ページでコントローラーが見つかりません。それらを必要とするビューにスクリプトとして明示的に追加する必要がありますか?それとも、すべてのページにすべてのコントローラーファイルを含める必要がありますか?
Sinaesthetic

2
最初の呼び出しだけに[]が必要な理由を明確にしていただきありがとうございます。
ジムB.

49

どちらの回答も技術的には正しいですが、この回答には別の構文の選択肢を紹介したいと思います。このimhoにより、注入で何が起こっているかを読みやすくしたり、区別したりできます。

ファイル1

// Create the module that deals with controllers
angular.module('myApp.controllers', []);

ファイル2

// Here we get the module we created in file one
angular.module('myApp.controllers')

// We are adding a function called Ctrl1
// to the module we got in the line above
.controller('Ctrl1', Ctrl1);

// Inject my dependencies
Ctrl1.$inject = ['$scope', '$http'];

// Now create our controller function with all necessary logic
function Ctrl1($scope, $http) {
  // Logic here
}

ファイル3

// Here we get the module we created in file one
angular.module('myApp.controllers')

// We are adding a function called Ctrl2
// to the module we got in the line above
.controller('Ctrl2', Ctrl2);

// Inject my dependencies
Ctrl2.$inject = ['$scope', '$http'];

// Now create our controller function with all necessary logic
function Ctrl2($scope, $http) {
  // Logic here
}

興味深いのは、コントローラを登録するために複数のファイルに行くから私を保つない
mrwaim

4
このようなコーディングがたくさんあります。利点は何ですか?$ injectと関数を別々にすること。
Alaksandarジーザスジェネ

2
コードが読みやすくなると思います。私は正確に何が注入されているのか知っています。行ごとの「懸念の分離」と考えてください。
jason328

2
このようなコードは、より読みやすいコードを生成するだけでなく、デバッグがはるかに簡単になり、ネストされたコールバックコードの量を減らします(github.com/johnpapa/angular-styleguide/blob/master/a1/…を参照)
rfornal

これを1000回+1できるとしたら-ブラボー!
Dan Chase、

17

このソリューションはどうですか?ファイル内のモジュールとコントローラー(ページの最後)複数のコントローラー、ディレクティブなどで動作します。

app.js

var app = angular.module("myApp", ['deps']);

myCtrl.js

app.controller("myCtrl", function($scope) { ..});

html

<script src="app.js"></script>
<script src="myCtrl.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">

Googleには、 私が本当にコンテキストごとにグループ化したいAngular App Structureのベストプラクティスの推奨事項もあります。1つのフォルダー内のすべてのhtmlではなく、たとえばログイン用のすべてのファイル(html、css、app.js、controller.jsなど)。したがって、モジュールで作業すると、すべてのディレクティブが見つけやすくなります。


3

簡潔にするために、グローバル変数に依存しないES2015サンプルを次に示します

// controllers/example-controller.js

export const ExampleControllerName = "ExampleController"
export const ExampleController = ($scope) => {
  // something... 
}

// controllers/another-controller.js

export const AnotherControllerName = "AnotherController"
export const AnotherController = ($scope) => {
  // functionality... 
}

// app.js

import angular from "angular";

import {
  ExampleControllerName,
  ExampleController
} = "./controllers/example-controller";

import {
  AnotherControllerName,
  AnotherController
} = "./controllers/another-controller";

angular.module("myApp", [/* deps */])
  .controller(ExampleControllerName, ExampleController)
  .controller(AnotherControllerName, AnotherController)

1
名前付き関数を使用すると、タイピングの手間を省くことができます..それらには便利なプロパティがあるnameのでExampleCtrl.name、複製する代わりに単純に使用できます。
Antti Pihlaja

0

それほど優雅ではありませんが、実装変数は非常に単純です-グローバル変数を使用します。

「最初の」ファイルで:


window.myApp = angular.module("myApp", [])
....

「second」、「third」など:


myApp.controller('MyController', function($scope) {
    .... 
    }); 

このコードを使用していますが、それでもコントローラーをロードできませんか?エラーがスローされます:エラー:[ng:areq]引数 'ProductCtrl'は関数ではないため、未定義です。
QViet 2015

7
これは本当に悪い習慣です
ブレンダン

@Kim Jong Un作成したモジュールにコントローラーを追加/連結しないと、このエラーが表示されます。それが動作しますので、次の構文を使用する場合:angular.module('myApp').controller('ProductCtrl', ['$scope', '$http', function($scope, $http){ //Your ProductCtrl code goes here }]);
Devner

1
@ブレンダン、単に何かが悪い習慣であると述べることは、何もないよりはましですが、多くはありません。それが悪い習慣が他人を助けることになる理由を教えてください。
Mawgはモニカを2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.