Reputation: 911
I'm having an issue getting a watch to work within a directive. I've put together a simple example here. http://plnkr.co/edit/A7zbrsh8gJhdpM30ZH2P
I have a service and two directives. One directive changes a property in the service, and another directive has a watch on that property. I expected the watch to fire when the property is changed but it doesn't.
I've seen a few other questions like this on the site, but the accepted solutions on them have not worked here. I've considered using $broadcast or trying to implement an observer, but it seems like this should work and I don't want to over complicate things if possible.
Upvotes: 9
Views: 6173
Reputation: 12283
Mark Rajcok' answer is incomplete. Even with angular.copy(), $watch listener will be called once and never again.
You need to $watch a function:
$scope.$watch(
// This is the important part
function() {
return demoService.currentObject;
},
function(newValue, oldValue) {
console.log('demoService.currentObject has been changed');
// Do whatever you want with demoService.currenctObject
},
true
);
Here the plunker that works: http://plnkr.co/edit/0mav32?p=preview
Open your browser console to see that both the directive and the demoService2 are notified about demoService.currentObject changes.
And btw angular.copy() is not even needed in this example.
Upvotes: 28
Reputation: 364677
Instead of
this.currentObject = newObject;
use
angular.copy(newObject, this.currentObject);
With the original code, the viewer
directive is watching the original object, {}
. When currentObject
is set to newObject
, the $watch is still looking for a change to the original object, not newObject
.
angular.copy() modifies the original object, so the $watch sees that change.
Upvotes: 4