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(); }); } }; });
$apply() function will execute custom code and then it will call $scope. $digest() function forcefully to check all watch list variables and update variable values in view if any changes found for watch list variables. In most of the time angularjs will use $scope.
When you create a data binding from somewhere in your view to a variable on the $scope object, AngularJS creates a "watch" internally. A watch means that AngularJS watches changes in the variable on the $scope object. The framework is "watching" the variable. Watches are created using the $scope.
The $scope object used by views in AngularJS are organized into a hierarchy. There is a root scope, and the $rootScope can has one or more child scopes.
Angular scopes include a variable called $parent (i.e. $scope. $parent ) that refer to the parent scope of a controller. If a controller is at the root of the application, the parent would be the root scope ( $rootScope ). Child controllers can therefore modify the parent scope since they access to it.
In angularjs $watch () function is used to watch the changes of variables in $scope object. Generally the $watch () function will create internally in angularjs to handle variable changes in application.
In angularjs $watch() function is used to watch the changes of variables in $scope object. Generally the $watch() function will create internally in angularjs to handle variable changes in application. Suppose in our angularjs applications if we want to create custom watch for some actions then it’s better to use $scope.watch function.
The parent scope will propagate the $digest()event. The scope can be removed from the scope hierarchy using $destroy(). $destroy()must be called on a scope when it is desired for the scope and its child scopes to be permanently detached from the parent and thus stop participating in model change detection and listener notification by invoking.
Child scopes are created using the $new()method. (Most scopes are created automatically when compiled HTML template is executed.) See also the Scopes guidefor an in-depth introduction and usage examples. Inheritance A scope can inherit from a parent scope, as in this example:
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(); }); } }; });
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