在 $watch 中使用 $apply
Using a $apply inside a $watch
我有一个非隔离作用域指令。我不想隔离它,因为它需要与其他指令一起位于元素上。但是我需要看范围内的项目。所以我尝试了这个:
scope.$watch(function() {
return scope.$apply(attrs.myAttribute);
}, function(val) {
return val ? doSomething():doSomethingElse();
});
这不起作用,因为 angular 抛出摘要循环已在进行中错误。所以我的问题是,如何使用非隔离指令动态监视范围内的项目。
谢谢,
如果项目已经在范围内,则不完全确定您在观看该项目时遇到的困难是什么。你能详细说明一下吗?无论如何,这里有两个解决方案应该涵盖几乎所有情况。要观察属性变化,请观察以下...
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
观看属性演示
您不想在 $watch
回调中调用 $apply
,因为 scope.$watch
会在内部为您调用 $apply
,这就是为什么您会得到 "digest cycle already in progress error"错误。
相反,你可以简单地做:
scope.$watch(attrs.myAttribute, function(val){
return val ? doSomething() : doSomethingElse();
};
设置为 myAttribute
的表达式将根据指令所在元素的范围进行评估,因为正如您提到的那样,它不是孤立的。当 return 值改变时,回调函数将被调用。
例如,如果您的 HTML 看起来像这样
<div myNoNewScopeDirective myAttribute="doThis(value)"></div>
doThis(value)
将根据与 div 元素关联的范围进行评估,其 return 值将由您的 myNoNewScopeDirective
监视。因此,对此类值的任何更改都将触发您提供的回调,当 val
为真时,将调用 doSomething
。
我有一个非隔离作用域指令。我不想隔离它,因为它需要与其他指令一起位于元素上。但是我需要看范围内的项目。所以我尝试了这个:
scope.$watch(function() {
return scope.$apply(attrs.myAttribute);
}, function(val) {
return val ? doSomething():doSomethingElse();
});
这不起作用,因为 angular 抛出摘要循环已在进行中错误。所以我的问题是,如何使用非隔离指令动态监视范围内的项目。
谢谢,
如果项目已经在范围内,则不完全确定您在观看该项目时遇到的困难是什么。你能详细说明一下吗?无论如何,这里有两个解决方案应该涵盖几乎所有情况。要观察属性变化,请观察以下...
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
您不想在 $watch
回调中调用 $apply
,因为 scope.$watch
会在内部为您调用 $apply
,这就是为什么您会得到 "digest cycle already in progress error"错误。
相反,你可以简单地做:
scope.$watch(attrs.myAttribute, function(val){
return val ? doSomething() : doSomethingElse();
};
设置为 myAttribute
的表达式将根据指令所在元素的范围进行评估,因为正如您提到的那样,它不是孤立的。当 return 值改变时,回调函数将被调用。
例如,如果您的 HTML 看起来像这样
<div myNoNewScopeDirective myAttribute="doThis(value)"></div>
doThis(value)
将根据与 div 元素关联的范围进行评估,其 return 值将由您的 myNoNewScopeDirective
监视。因此,对此类值的任何更改都将触发您提供的回调,当 val
为真时,将调用 doSomething
。