AngularJS
コントローラ
サーチ…
構文
- <htmlElement ng-controller = "controllerName"> ... </ htmlElement>
- <script> app.controller( 'controllerName'、controllerFunction); </ script>
最初のコントローラ
コントローラは、スコープを保持し、ページ内の特定のアクションを処理するために、Angularで使用される基本構造です。各コントローラはHTMLビューと結合されています。
以下はAngularアプリの基本定型文です:
<!DOCTYPE html>
<html lang="en" ng-app='MyFirstApp'>
<head>
<title>My First App</title>
<!-- angular source -->
<script src="https://code.angularjs.org/1.5.3/angular.min.js"></script>
<!-- Your custom controller code -->
<script src="js/controllers.js"></script>
</head>
<body>
<div ng-controller="MyController as mc">
<h1>{{ mc.title }}</h1>
<p>{{ mc.description }}</p>
<button ng-click="mc.clicked()">
Click Me!
</button>
</div>
</body>
</html>
ここで注意すべき点がいくつかあります。
<html ng-app='MyFirstApp'>
ng-app
アプリケーション名を設定すると、外部のJavascriptファイルでアプリケーションにアクセスできます。これについては、以下で説明します。
<script src="js/controllers.js"></script>
コントローラとそのアクション/データを定義するJavascriptファイルが必要です。
<div ng-controller="MyController as mc">
ng-controller
属性は、そのDOM要素とそれより下の(再帰的に)子要素であるすべての要素のコントローラを設定します。
同じコントローラー(この場合はMyController
)の複数を... as mc
すると、このコントローラーのインスタンスに別名を与えることができます。
<h1>{{ mc.title }}</h1>
{{ ... }}
記法はAngular式です。この場合、これは<h1>
要素の内部テキストをmc.title
の値にmc.title
ます。
注意: Angularはデュアルウェイのデータバインディングを採用しています。 mc.title
、 mc.title
値を更新する方法に関係なく、コントローラとページの両方に反映されます。
また、角度式はコントローラを参照する必要はありません 。 Angular式は、 {{ 1 + 2 }}
や{{ "Hello " + "World" }}
ように簡単にできます。
<button ng-click="mc.clicked()">
ng-click
はAngularディレクティブです。この場合、ボタンのClickイベントをバインドして、 MyController
インスタンスのMyController
clicked()
関数をトリガしclicked()
。
これらのことを念頭に置いて、 MyController
コントローラの実装を書いてみましょう。上記の例では、このコードをjs/controller.js
記述します。
まず、Javascriptで角度アプリをインスタンス化する必要があります。
var app = angular.module("MyFirstApp", []);
ここで渡す名前は、 ng-app
ディレクティブでHTMLに設定した名前と同じng-app
。
appオブジェクトができたので、それを使ってコントローラを作成することができます。
app.controller('MyController', function(){
var ctrl = this;
ctrl.title = "My First Angular App";
ctrl.description = "This is my first Angular app!";
ctrl.clicked = function(){
alert("MyController.clicked()");
};
});
注:コントローラインスタンスの一部になりたいものについては、 this
キーワードを使用します。
これは、単純なコントローラを構築するために必要なすべてです。
コントローラの作成
angular
.module('app')
.controller('SampleController', SampleController)
SampleController.$inject = ['$log', '$scope'];
function SampleController($log, $scope){
$log.debug('*****SampleController******');
/* Your code below */
}
注: .$inject
は、あなたの依存関係が縮小後にスクランブルされないようにします。また、名前付き関数で順番に並んでいることを確認してください。
コントローラの作成、分散安全
コントローラの作成を小型化から保護するには、いくつかの方法があります。
最初は、インライン配列注釈と呼ばれます。次のようになります。
var app = angular.module('app');
app.controller('sampleController', ['$scope', '$http', function(a, b){
//logic here
}]);
コントローラメソッドの2番目のパラメータは、依存関係の配列を受け入れることができます。あなたが見ることができるように私が定義した$scope
と$http
れるコントローラ機能のパラメータに対応しなければならないだろうa
$scope
、およびb
なり$http
。アレイの最後の項目はコントローラ機能である必要があります。
2番目のオプションは、 $inject
プロパティを使用しています。次のようになります。
var app = angular.module('app');
app.controller('sampleController', sampleController);
sampleController.$inject = ['$scope', '$http'];
function sampleController(a, b) {
//logic here
}
これは、インライン配列注釈と同じことを行いますが、一方のオプションよりも好きなものに対しては、異なるスタイルを提供します。
注入された依存関係の順序は重要です
配列形式を使用して依存関係を注入するときは、依存関係のリストがコントローラ関数に渡される引数の対応するリストと一致することを確認してください。
次の例では、 $scope
と$http
が逆になっています。これにより、コードに問題が発生します。
// Intentional Bug: injected dependencies are reversed which will cause a problem
app.controller('sampleController', ['$scope', '$http',function($http, $scope) {
$http.get('sample.json');
}]);
Angular JSにおけるControllerAsの使用
Angular $scope
は、コントローラとビューの間の接着剤で、データバインディングのすべてのニーズに役立ちます。コントローラーは、コントローラーとビューをバインドするもう1つの方法で、主に使用することをお勧めします。基本的には、Angular(つまり、$ scopeとController As)の2つのコントローラ構造体です。
コントローラの使用方法の違い -
controllerAsビューの構文
<div ng-controller="CustomerController as customer">
{{ customer.name }}
</div>
controllerAsコントローラの構文
function CustomerController() {
this.name = {};
this.sendMessage = function() { };
}
vmを備えたコントローラ
function CustomerController() {
/*jshint validthis: true */
var vm = this;
vm.name = {};
vm.sendMessage = function() { };
}
controllerAs
は$scope
超える構文的砂糖です。ビューにバインドして$scope
メソッドにアクセスすることはできます。 controllerAs
を使用controllerAs
ことは、角度のコアチームによって提案されたベストプラクティスの1つです。これには多くの理由がありますが、そのほとんどが -
$scope
は、中間オブジェクトを介してコントローラからビューにメンバーを公開しています。これをthis.*
に設定することで、コントローラからビューに公開したいものだけを公開することができます。また、これを使用する標準的なJavaScriptの方法に従います。controllerAs
構文を使用controllerAs
と、わかりやすいコードが得られ、$parent
構文を使用する代わりに、親コントローラのエイリアス名を使用して親プロパティにアクセスできます。これは、より文脈に沿い、読みやすく、 "点を打たずに"発生する可能性のある参照問題を避ける、ビュー内の「ドット付き」オブジェクトへのバインディングの使用を促進する(例えば、名前の代わりにcustomer.nameなど)。
ネストされたコントローラを持つビューで
$parent
呼び出しを使用しないようにします。controllerAs
構文を使用する場合は、キャプチャ変数を使用します。 ViewModelを表すvm
などの一貫した変数名を選択します。なぜなら、this
キーワードは文脈的なものであり、コントローラ内の関数内で使用されると、そのコンテキストを変更する可能性があるからです。これのコンテキストをキャプチャすることで、この問題が発生することはありません。
注: controllerAs
構文を使用controllerAs
と、現在のコントローラへの現在のスコープ参照に追加されるので、フィールドとして使用できます
<div ng-controller="Controller as vm>...</div>
vm
は$scope.vm
として利用できます。
ミニネーションセーフ角度制御器の作成
ミニセーフティ角度コントローラを作成するには、 controller
機能パラメータを変更します。
module.controller
関数の2番目の引数には配列を渡す必要がありmodule.controller
最後のパラメータはコントローラ関数で 、その前のすべてのパラメータは各注入された値の名前です。
これは通常のパラダイムとは異なります。それは注入された引数でコントローラ機能を引き受けます。
与えられた:
var app = angular.module('myApp');
コントローラーは次のようになります。
app.controller('ctrlInject',
[
/* Injected Parameters */
'$Injectable1',
'$Injectable2',
/* Controller Function */
function($injectable1Instance, $injectable2Instance) {
/* Controller Content */
}
]
);
注: 注入されたパラメーターの名前は一致する必要はありませんが、順序どおりにバインドされます。
これは次のようなものに縮小されます:
var a=angular.module('myApp');a.controller('ctrlInject',['$Injectable1','$Injectable2',function(b,c){/* Controller Content */}]);
縮小プロセスは、のすべてのインスタンスに置き換えられますapp
して、のすべてのインスタンスa
$Injectable1Instance
とb
、およびのすべてのインスタンス$Injectable2Instance
とc
。
ネストされたコントローラ
ネスティングコントローラは$scope
もチェーン化します。変更$scope
ネストされたコントローラ内の変数は、同じ変更$scope
親コントローラに変数を。
.controller('parentController', function ($scope) {
$scope.parentVariable = "I'm the parent";
});
.controller('childController', function ($scope) {
$scope.childVariable = "I'm the child";
$scope.childFunction = function () {
$scope.parentVariable = "I'm overriding you";
};
});
さて、これらの両方を処理しようとしましょう。
<body ng-controller="parentController">
What controller am I? {{parentVariable}}
<div ng-controller="childController">
What controller am I? {{childVariable}}
<button ng-click="childFunction()"> Click me to override! </button>
</div>
</body>
ネスティングコントローラにはメリットがあるかもしれませんが、そうする際には1つ注意が必要です。 ngController
ディレクティブを呼び出すと、コントローラの新しいインスタンスが作成され、混乱や予期しない結果が生じることがあります。