Angularjs监视父范围的变化

我正在写一个指令,我需要观察父变化的范围。 不知道如果我这样做的首选方式,但它不与以下代码工作:

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

这是login窗口的负载,但不会再次,即使overlaytype被改变。

我怎样才能看overlaytype的变化?

编辑:这是整个指令。 不完全确定为什么我要得到一个孩子的范围

 /* 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(); }); } }; }); 

你应该有你的子范围的数据属性,范围使用父级和子级范围之间的原型inheritance。

此外, $ watch方法所期望的第一个参数是一个expression式或一个函数来计算,而不是一个variables的值,所以你应该发送它。

如果你想观察父作用域的属性,你可以使用父作用域的$watch方法。

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

编辑2016年:上面应该工作得很好,但它不是一个干净的devise。 尝试使用指令或组件,并将其依赖关系声明为绑定。 这应该会导致更好的性能和更清洁的devise。

我build议你使用$控制器之间的广播来执行此操作,这似乎是更多的父/子控制器之间的angular度方式通信

这个概念很简单,您可以在父控制器中观察值,然后当发生修改时,可以将其广播并将其捕获到子控制器中

这是一个演示它的小提琴: http : //jsfiddle.net/DotDotDot/f733J/

父控制器中的部分如下所示:

 $scope.$watch('overlaytype', function(newVal, oldVal){ if(newVal!=oldVal) $scope.$broadcast('overlaychange',{"val":newVal}) }); 

并在子控制器中:

 $scope.$on('overlaychange', function(event, args){ console.log("change detected") //any other action can be perfomed here }); 

这个解决scheme的好处是,如果你想看另一个孩子控制器的修改,你可以捕捉同一个事件

玩的开心

编辑:我没有看到你最后编辑,但我的解决scheme也适用于该指令,我更新了以前的小提琴( http://jsfiddle.net/DotDotDot/f733J/1/

我修改了你的指令,强制它创build一个子范围并创build一个控制器:

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

如果您正在寻找在子范围内观察父范围variables,则可以在$watch上添加“ true作为第二个参数。 每当您的对象被修改时,这将触发您的手表

 $scope.$watch("searchContext", function (ctx) { ... }, true); 

好吧,我花了一段时间,这里是我的两美分,我也喜欢事件选项,虽然:

更新小提琴 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"); }); 

我在这里展示的是,你可以有一个variables,从孩子和父母有两种方式绑定,但不要求孩子达到它的父母获得一个属性。 如果你在指令上面添加一个新的父对象,那么达成事情的趋势会变得疯狂。

如果你input框中,它将更新控制器上的模型,这又将被绑定到指令的属性,所以它将在指令中更新。 在指令链接function中,它有一个监视设置,所以无论何时,范围variables改变它增加一个计数器。

查看有关隔离范围和使用= @或&here: http : //www.egghead.io/之间的区别的更多信息