I have a directive with isolate scope which takes a scope variable by reference
angular.module('myApp')
.directive('myDirective', function() {
return {
scope: {
items: '='
},
templateUrl: 'template.html',
replace: true,
controller: 'myDirectiveCtrl',
controllerAs: 'ctrl'
};
})
.controller('myDirectiveCtrl', function($scope) {
this.items = $scope.items;
});
This is passed in like so:
<div my-directive items='items'></div>
In the external controller data is asynchronously loaded and the scope items passed into the directive updated:
angular.module('myApp', [])
.controller('myCtrl', function($scope) {
$scope.setItems = function() {
$scope.items = [
'Here',
'There',
'Everywhere'
];
};
});
When the data is loaded, the scope outside my directive updates, but inside it doesn't
My html:
<div my-directive items='items'></div> <!-- this doesn't update -->
Outside directive
<ul ng-repeat='i in items'> <!-- this does update -->
<li>{{i}}</lu>
</ul>
<button ng-click="setItems()">Set items</button>
How can I get my scope inside my directive to update? Do I
Plunker here
When Angular first runs your directive's controller function, your $scope.items === undefined
, so when you do this.items = $scope.items
, your this.items === undefined
too.
That's it. After that there is nothing that changes this.items
.
This is unlike $scope.items
. $scope.items
is two-way bound to the outer scope, so whenever Angular detects a change externally, it sets the isolated scope variable.
The easiest way (and most suitable, in my opinion) is to use the $scope
property directly in the directive:
<div>
Inside directive
<ul ng-repeat="i in items">
<li>{{ i }}</li>
</ul>
</div>
If you want to use your controller as ViewModel instead of scope (I don't know why you would), you could do:
$scope.$watchCollection("items", function(newVal, oldVal) {
ctrl.items = newVal;
});
EDIT:
In Angular 1.3 you can also do bindToController: true
in the directive's definition, so that the controller property "items
" will get the two-way binding that $scope.items
gets. Then, you don't even need to do this.items = $scope.items;
:
Your forked plunker to illustrate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With