我正在编写指令,我需要观察更改的父作用域。我不确定我是否喜欢这样做,但它不能使用以下代码:
scope.$watch(scope.$parent.data.overlaytype,function() {
console.log("Change Detected...");
})
这会记录窗口加载,但即使更改了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();
});
}
};
});
答案 0 :(得分:73)
如果要查看父作用域的属性,可以使用父作用域中的$watch
方法。
//intead of $scope.$watch(...)
$scope.$parent.$watch('property', function(value){/* ... */});
2016年编辑: 上面应该工作得很好,但它并不是一个干净的设计。尝试使用directive或component,并将其依赖项声明为绑定。这应该会带来更好的性能和更清洁的设计。
答案 1 :(得分:21)
我建议你使用控制器之间的$ broadcast来执行此操作,这似乎是父/子控制器之间通信的角度方式
概念很简单,你在父控制器中观察值,然后,当发生修改时,你可以广播它并在子控制器中捕获它
这是一个演示它的小提琴: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
});
使用此解决方案的好处是,如果您想在另一个子控制器中观看修改,您可以捕获相同的事件
玩得开心
编辑:我没有看到你上次编辑,但我的解决方案也适用于指令,我更新了前一个小提琴(http://jsfiddle.net/DotDotDot/f733J/1/)
我修改了你的指令以强制它创建子范围并创建一个控制器:
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();
});
}
};
});
答案 2 :(得分:7)
您的子范围应该具有 data 属性,范围使用父范围和子范围之间的原型继承。
此外, $ watch 方法所期望的第一个参数是要计算的表达式或函数,而不是变量中的值。所以你应该发送它。
答案 3 :(得分:6)
如果您正在寻找在子范围内观看父范围变量,您可以在true
上添加$watch
作为第二个参数。这将在每次修改对象时触发您的手表
$scope.$watch("searchContext", function (ctx) {
...
}, true);
答案 4 :(得分:2)
好吧,我花了一段时间在这里是我的两分钱,我也喜欢这个活动选项:
更新小提琴 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");
});
我在这里展示的是你可以拥有一个变量,它具有来自孩子和父母的双向绑定,但不要求孩子达到它的父亲来获得属性。如果你在指令上面添加一个新的父级,那么伸手去抓东西的倾向会变得疯狂。
如果在框中键入,它将更新控制器上的模型,而这又会绑定到指令上的属性,因此它将在指令中更新。在指令链接功能中,它具有监视设置,因此只要范围变量发生变化,它就会递增计数器。
详细了解隔离范围以及使用= @或&amp;的差异在这里:http://www.egghead.io/