在$ watch中使用$ apply

时间:2015-10-20 18:01:05

标签: javascript html angularjs angularjs-directive anguarjs-digest-cycle

我有一个非隔离范围指令。我不想隔离它,因为它需要与其他指令一起使用元素。但我需要在范围内观看一个项目。所以我尝试了这个:

scope.$watch(function() {
     return scope.$apply(attrs.myAttribute);
}, function(val) {
     return val ? doSomething():doSomethingElse();
});

这不起作用,因为角度抛出已经在进行中的摘要周期错误。所以我的问题是,如何使用非隔离指令动态观察范围内的项目。

谢谢,

2 个答案:

答案 0 :(得分:2)

如果项目已在范围内,则不完全确定您正在观看该项目的困难。你能详细说明一下吗?无论如何,这里有两个解决方案应该涵盖几乎所有情况。要观察属性更改,请观察以下内容......

scope.$watch(function() {
    return elem.attr('my-attribute');
}, function(n, o) {
    if(n) 
        console.log(n);
});

JSFiddle Link - 观看属性演示

但是,我怀疑你在范围内获得该项目时遇到困难。如果是这样,这里有一种通过$observe分配它的方法,然后从那里观察它而没有孤立......

attrs.$observe('myAttribute', function(value) {
    scope.myValue = value;
});

scope.$watch('myValue', function(n, o) {
    if(n) 
        console.log(n);
});

JSFiddle Link - 通过$observe

观看属性演示

答案 1 :(得分:1)

您不想在$apply回调中拨打$watch,因为scope.$watch内部为您调用了$apply,这就是您获取&scope.$watch(attrs.myAttribute, function(val){ return val ? doSomething() : doSomethingElse(); }; 的原因#34;摘要周期已在进行中错误"错误。

相反,您可以这样做:

myAttribute

设置为<div myNoNewScopeDirective myAttribute="doThis(value)"></div> 的表达式将根据您的指令所在元素的范围进行评估,因为就像您提到的那样,它不是孤立的。当返回值改变时,将调用回调函数。

例如,如果您的HTML看起来像这样

doThis(value)

myNoNewScopeDirective将根据与div元素关联的范围进行评估,并且val将监视其返回值。因此,对此类值的任何更改都会触发您提供的回调,并且当doSomething真实时,{{1}}将被调用。