Angularjs oversee parental reach change

I am writing a directive and I need to look at the parent area for change. Not sure if I am doing this in the preferred way, but not working with the following code:

scope.$watch(scope.$parent.data.overlaytype,function() { console.log("Change Detected..."); }) 

This is it that is registered when the window loads, but never again, even when the overlaytype is changed.

How can I watch overlaytype for change?

Edit: here is the whole Directive. Not quite sure why I get the kids area.

 /* 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(); }); } }; }); 
+42
javascript scope angularjs
Jul 24 '13 at 15:40
source share
5 answers

You must have a data property in the area of ​​your child, the applications use prototype inheritance between the parent and child areas.

In addition, the first argument that the $ watch method expects is an expression or function to evaluate, not the value of a variable. Therefore you should send this instead.

+7
Jul 24 '13 at 15:47
source share

If you want to see the property of the parent area, you can use the $watch method from the parent area.

 //intead of $scope.$watch(...) $scope.$parent.$watch('property', function(value){/* ... */}); 

EDIT 2016: The above should work very well, but this is not a completely clean design. Try using directive or component instead and declare your dependencies as bindings. This should lead to better performance and a cleaner design.

+68
Mar 31 '14 at 12:47
source share

I would suggest you use $ broadcast between the controller to accomplish this, which seems to be a more angular way to communicate between parent / child controllers

The concept is simple, you look at the value in the parent controller, then when a modification occurs, you can translate it and intercept it in the child controller

Here is a fiddle demonstrating this: http://jsfiddle.net/DotDotDot/f733J/

The part in the parent controller is as follows:

 $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 }); 

A good point with this solution, if you want to see the changes in another child controller, you can just catch the same event

Good luck

Edit: I did not see the last edit, but my solution also works for the directive, I updated the previous fiddle ( http://jsfiddle.net/DotDotDot/f733J/1/ )

I changed your directive to make it 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(); }); } }; }); 
+19
Jul 24 '13 at 16:02
source share

If you are looking for a view of the parent sphere variable inside the child scope, you can add true as the second argument to $watch . It will call your watch every time your object is changed.

 $scope.$watch("searchContext", function (ctx) { ... }, true); 
+5
Aug 26 '15 at 8:44
source share

It's good that it took me a while here, my two cents, I also like the event option:

Updated fiddle http://jsfiddle.net/enU5S/1/

HTML

 <div ng-app="myApp" ng-controller="MyCtrl"> <input type="text" model="model.someProperty"/> <div awesome-sauce some-data="model.someProperty"></div> </div> 

Js

 angular.module("myApp", []).directive('awesomeSauce',function($window){ return { restrict : "A", template: "<div>Ch-ch-ch-changes: {{count}} {{someData}}</div>", scope: {someData:"="}, link : function(scope,elem,attrs){ scope.count=0; scope.$watch("someData",function() { scope.count++; }) } }; }).controller("MyCtrl", function($scope){ $scope.model = {someProperty: "something here"); }); 

What I am showing here is that you can have a variable that has two-way binding from the child and the parent, but does not require the child to reach its parent in order to get the property. The tendency to achieve something may go crazy if you add a new parent over the directive.

If you enter in the field, it will update the model on the controller, this, in turn, is tied to the property in the directive so that it is updated in the directive. Inside the directive reference function, it has a clock setting, so at any time when the region variable changes, it increments the counter.

Read more about the isolation area and the differences between using = @ and here: http://www.egghead.io/

+2
Jul 24 '13 at 16:27
source share



All Articles