AngularJSのdirectivを使う場合、独自のscopeを作成できるが、その仕組みがいまいちわからない。
まず、簡単なところから。
属性のscopeをdirectivBのように{}を設定すると。
独自のscopeを作成する。
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
<directiv-A></directiv-A>
<directiv-B></directiv-B>
</body>
</html>
js
angular.module('App', [])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.value = '親のscopeを継承'
}])
.directive('directivA', function() {
return {
restrict: 'E',
template: '<div>scope:{{value}}</div>'
};
})
.directive('directivB', function() {
return {
restrict: 'E',
scope: {},
template: '<div>scope:{{value}}</div>'
};
})
出力結果
scope:親のscopeを継承
scope
他にも下記設定方法がある。
- scope: false ・・・scope属性を設定しない場合と同様の結果。デフォルト値はfalse。
- scope: true ・・・親scopeを継承し、新しいscopeを作成する。
- scope: {} ・・・独立したスコープを作成する
scope: false/tureの設定サンプル
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
<directiv-A></directiv-A>
<directiv-A></directiv-A>
<directiv-A></directiv-A>
<directiv-B></directiv-B>
<directiv-B></directiv-B>
<directiv-B></directiv-B>
</body>
</html>
js
angular.module('App', [])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.value = '親のscopeを継承'
}])
.directive('directivA', function() {
return {
restrict: 'E',
scope: false,
template: '<div>scope: true:{{value}} id:{{id}}</div>',
controller: function($scope) {
$scope.id = $scope.$id;
}
}
})
.directive('directivB', function() {
return {
restrict: 'E',
scope: true,
template: '<div>scope: true:{{value}} id:{{id}}</div>',
controller: function($scope) {
$scope.id = $scope.$id;
}
};
});
出力結果
scope: false:親のscopeを継承 id:2
scope: false:親のscopeを継承 id:2
scope: false:親のscopeを継承 id:2
scope: true:親のscopeを継承 id:3
scope: true:親のscopeを継承 id:4
scope: true:親のscopeを継承 id:5
独立したスコープを作成する
scope:'='を使う
子Scopeと親Scopeを双方向バインディングさせる。
親Scopeが変更されれば、子Scopeも変更される。子が変更されれば、親も変更される。
親scopeで子scopeの管理がしやすくなる。
js
angular.module('App', [])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.test = '双方向でバインド'
$scope.test2 = '双方向でバインド2'
}])
.directive('directivA', function() {
return {
restrict: 'E',
template:'<div>directivA : {{itemA}}</div>',
scope: {
itemA: '='
}
};
});
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
<div>{{test}}</div>
<div>{{test2}}</div>
<br>
<directiv-A item-A="test"></directiv-A>
<directiv-A item-A="test2"></directiv-A>
</body>
</html>
出力結果
双方向でバインド
双方向でバインド2
directivA : 双方向でバインド
directivA : 双方向でバインド2
scope:'@'を使う
scopeのプロパティに指定した文字列がそのまま渡ります。
親scopeにはバインドされない。
js
angular.module('App', [])
.controller('AppCtrl', ['$scope', function($scope) {}])
.directive('directivB', function() {
return {
restrict: 'E',
template: '<div>directivB : {{itemB}}</div>',
scope: {
itemB: '@'
}
};
});
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
<directiv-B item-B="文字列が入ります"></directiv-B>
</body>
</html>
出力結果
directivB : 文字列が入ります
scope:'&'を使う
関数を指定する。(配列とか、数値とか、文字列とか指定できるみたいだが、関数を指定することが多いようです)
例1
js
angular.module('App', [])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.func = function() {
$scope.message = 'こんにちは';
}
}])
.directive('directivC', function() {
return {
restrict: 'E',
scope: {
itemC: '&'
},
controller: function($scope) {
$scope.itemC();
}
};
});
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
{{message}}
<directiv-C item-C="func()"></directiv-C>
</body>
</html>
出力結果
こんにちは
例2
js
angular.module('App', [])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.func = function(mess){
console.log('こんにちは')
}
}])
.directive('directivC', function() {
return {
restrict: 'E',
template: '<button ng-click="itemC()">ボタン</button>',
scope: {
itemC: '&'
}
};
});
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
<directiv-C item-C="func(message)"></directiv-C>
</body>
</html>
出力結果
こんにちは
例3
引数を連携する。
js
angular.module('App', [])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.func = function(mes, mes2) {
$scope.message = mes + mes2;
}
}])
.directive('directivC', function() {
return {
restrict: 'E',
scope: {
itemC: '&'
},
controller: function($scope) {
$scope.itemC({
mes: 'こんにちは',
mes2: '太郎さん'
});
}
};
});
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
{{message}}
<directiv-C item-C="func(mes,mes2)"></directiv-C>
</body>
</html>
出力結果
こんにちは太郎さん
例4
&で配列を入れてみる。
js
angular.module('App', [])
.controller('AppCtrl', ['$scope', function($scope) {
$scope.array = [1, 2, 3];
}])
.directive('directivC', function() {
return {
restrict: 'E',
scope: {
itemC: '&'
},
controller: function($scope) {
console.log($scope.itemC())
}
};
});
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
<directiv-C item-C="array"></directiv-C>
</body>
</html>
出力結果
[1, 2, 3]
これは'='を使えばいいのではないかと思うが、子scopeにバインドしたくない場合などに使うのかな・・・
まだ理解が浅い為、追記していく予定。