🅰️
ここらでDirective Scopeの@=&をまとめておきたいと思う
@=&
でピンと来た方、Directiveを使いこなしていますね!
AngularJSの規模が大きくなると、Viewの再利用性を高めるためDirectiveをたくさん自作することになります。再利用性を高めるということはDirectiveやTemplateの抽象度を高めるということになり、特定の$scope
に依存する書き方は好ましくありません。
そこでDirectiveに独自のScopeを定義します。
Directive Scope
Directiveは初期化時にscope
プロパティを持たせることで、独自のscope
を持たせることができます。
angular.module('myApp')
.directive('dirA', function () {
return {
restrict: 'E',
scope: {arr: '@'} // こんなやつ
};
})
ここには@=&
の符号が使用でき、様々なサイトでその意味、利用法が解説されているのですが、いまいち分からない。
ということで、実例を付けてまとめてみました。
例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sample</title>
</head>
<body ng-app="myApp">
<div ng-controller="SampleCtrlA">
<dir-a my-arr="arr"><span ng-repeat="a in arr">{{a}},</span></dir-a>
</div>
<div ng-controller="SampleCtrlB">
<dir-b my-arr="arr"><span ng-repeat="a in arr">{{a}},</span></dir-b>
</div>
<div ng-controller="SampleCtrlC">
<dir-c my-arr="arr"><span ng-repeat="a in arr">{{a}},</span></dir-c>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-route.js"></script>
<script>
angular.module('myApp', ['ngRoute']);
var link = function (scope, elem, attr) {
console.log(scope.arr);
scope.arr = [6, 7, 8, 9, 10];
console.log(scope.arr);
console.log(scope);
};
angular.module('myApp')
.directive('dirA', function () {
return {
restrict: 'E',
scope: {arr: '@myArr'},
link: link
};
})
.directive('dirB', function () {
return {
restrict: 'E',
scope: {arr: '=myArr'},
link: link
};
})
.directive('dirC', function () {
return {
restrict: 'E',
scope: {arr: '&myArr'},
link: link
};
});
function Ctrl($scope) {
$scope.arr = [1, 2, 3, 4, 5];
}
angular.module('myApp')
.controller('SampleCtrlA', ['$scope', Ctrl]);
angular.module('myApp')
.controller('SampleCtrlB', ['$scope', Ctrl]);
angular.module('myApp')
.controller('SampleCtrlC', ['$scope', Ctrl]);
</script>
</body>
</html>
console.log
に吐いてるので、ログを読めばそのまま動きが分かるはずです。以下の解説はこの動作からみた所感で、公式のリファレンスの引用ではありません。
@
- ViewのHTML内に書いた文字列がそのまま文字列として渡る。
- AngularJSの式として評価はされない。
- 筆者の使い方では、
link
内の$parse()
で扱うために@
にすることがある。
=
- ViewのHTML内に書いた文字列が評価され結果が渡る。
- 親Scopeとバインドされるので、Directive Scope内の変更で親も変化する。
- 一番よく使う。
&
- ViewのHTML内に書いた文字列の評価結果を返すための関数が渡る。
- 親Scopeとはバインドされない。
- 多くの解説で「Viewには関数を指定する」と見受けられるが、文字列、数値、配列、関数、なんでもいい。
-
scope.val
のように直接参照するとparentGet(scope, locals)
という関数が返ってくるだけである。- 値は
scope.val()
として取り出す。 - これが関数なら
scope.val()()
として実行する。
- 値は
- バインドされず式は評価されるので、用途を理解すると使いやすい。
@=&以降の書き方
よく忘れてエラーになるのが@=&
の書き方。
属性名を指定する場合scope: {arr: '=myArr'}
というように、キャメルケースで書くことで、HTML中では<directive my-arr="">
といったハイフン繋ぎで使えます。
何も書かない場合、そのままScopeのプロパティ名がHTML上での属性名になります。
× {arr: '=my-arr'} <directive my-arr="">
× {arr: '=myArr'} <directive myArr="">
○ {arr: '=myArr'} <directive my-arr="">
× {my-arr: '='} <directive my-arr=""> // そもそも文法として誤り
△ {'my-arr': '='} <directive my-arr=""> // 動くがチェーンできない
○ {myArr: '='} <directive my-arr="">
○ {myArr: '=arr'} <directive arr="">
あとは自作Directiveを量産するだけ!
Discussion