Angularjs watch for change in parent scope
I'm writing a directive and I need to watch the parent scope for a change. Not sure if I'm doing this the preferred way, but its not working with the following code:
scope.$watch(scope.$parent.data.overlaytype,function() {
console.log("Change Detected...");
})
This it logged on window load, but never again, even when overlaytype is changed.
How can I watch overlaytype
for a change?
Edit: here is the entire Directive. Not entirely sure why I'm getting a child scope
/* Center overlays vertically directive */
aw.directive('center',function($window){
return {
restrict : "A",
link : function(scope,elem,attrs){
var resize = function() {
var winHeight = $window.innerHeight - 90,
overlayHeight = elem[0].offsetHeight,
diff = (winHeight - overlayHeight) / 2;
elem.css('top',diff+"px");
};
var watchForChange = function() {
return scope.$parent.data.overlaytype;
}
scope.$watch(watchForChange,function() {
$window.setTimeout(function() {
resize();
}, 1);
})
angular.element($window).bind('resize',function(e){
console.log(scope.$parent.data.overlaytype)
resize();
});
}
};
});
If you want to watch a property of a parent scope you can use $watch
method from the parent scope.
//intead of $scope.$watch(...)
$scope.$parent.$watch('property', function(value){/* ... */});
EDIT 2016: The above should work just fine, but it's not really a clean design. Try to use a directive or a component instead and declare its dependencies as bindings. This should lead to better performance and cleaner design.
I would suggest you to use the $broadcast between controller to perform this, which seems to be more the angular way of communication between parent/child controllers
The concept is simple, you watch the value in the parent controller, then, when a modification occurs, you can broadcast it and catch it in the child controller
Here's a fiddle demonstrating it : http://jsfiddle.net/DotDotDot/f733J/
The part in the parent controller looks like that :
$scope.$watch('overlaytype', function(newVal, oldVal){
if(newVal!=oldVal)
$scope.$broadcast('overlaychange',{"val":newVal})
});
and in the child controller :
$scope.$on('overlaychange', function(event, args){
console.log("change detected")
//any other action can be perfomed here
});
Good point with this solution, if you want to watch the modification in another child controller, you can just catch the same event
Have fun
Edit : I didn't see you last edit, but my solution works also for the directive, I updated the previous fiddle ( http://jsfiddle.net/DotDotDot/f733J/1/ )
I modified your directive to force it to create a child scope and create a controller :
directive('center',function($window){
return {
restrict : "A",
scope:true,
controller:function($scope){
$scope.overlayChanged={"isChanged":"No","value":""};
$scope.$on('overlaychange', function(event, args){
console.log("change detected")
//whatever you need to do
});
},
link : function(scope,elem,attrs){
var resize = function() {
var winHeight = $window.innerHeight - 90,
overlayHeight = elem[0].offsetHeight,
diff = (winHeight - overlayHeight) / 2;
elem.css('top',diff+"px");
};
angular.element($window).bind('resize',function(e){
console.log(scope.$parent.data.overlaytype)
resize();
});
}
};
});