Reputation: 5791
Changes to my scope variable foo
are getting updated in the html. When that value is change inside the scope of a directive's controller, it isn't updating in the html.
What do I need to do to make it update?
I have a simple example:
app.js
var app = angular.module('app', []);
app.controller('ctrl', function($scope) {
$scope.foo = 99;
$scope.changeValue = function() {
$scope.foo = $scope.foo + 1;
}
});
app.directive('d1', function(){
return {
restrict: 'E',
scope: {
theFoo: '='
},
templateUrl: 'd1.html',
controller: 'd1Ctrl',
}
});
app.controller('d1Ctrl', function($scope) {
$scope.test = $scope.theFoo;
});
d1.html
<div>
<p>The value of foo is '{{theFoo}}'.</p>
<p>The value of test is '{{test}}'.</p>
</div>
inside index.html
<d1 the-foo='foo'>
</d1>
<button ng-click='changeValue()'>change value</button>
So in summary, {{theFoo}}
is updating, but {{test}}
isn't. Why?
Upvotes: 0
Views: 770
Reputation: 2969
here you have isolated the scope of the directive, so test
is not visible to the d1.html
, if you need to change test
along with the theFoo
you must first make it visible to the directive by
app.directive('d1', function(){
return {
restrict: 'E',
scope: {
theFoo: '=',
test : '=' //getting test as well
},
templateUrl: 'd1.html',
controller: 'd1Ctrl',
}
});
and in index.html you should pass the value to the test by
<d1 the-foo='foo' test='foo'></d1>
in the above code your controller is not much of a use , code will work fine even without this part controller: 'd1Ctrl'
.
with this example you dont have to use $watch
.
Upvotes: 0
Reputation: 171669
The reason is that $scope.foo
value is a primitive.
In the directive controller you only assign $scope.test
once when controller initializes. Primitives have no inheritance the way objects do so there is nothing that would change $scope.test
after that initial assignment
If you used an object instead to pass in ... inheritance would be in effect and you would see changes...otherwise you would need to watch $scope.theFoo
and do updates to $scope.test
yourself
Upvotes: 1
Reputation: 6813
The code you have in your controller only initializes to that value if it is indeed set at the time the controller is linked. Any subsequent changes are not going to work.
If you want to bind any subsequent changes, then you need to set a $watch statement either in your controller or a link function.
$scope.$watch( 'theFoo', function(val){ $scope.test = val; })
updated plunker - http://plnkr.co/edit/eWoPutIJrwxZj9XJu6QG?p=preview
Upvotes: 1