简体   繁体   English

在$ watch中使用$ apply

[英]Using a $apply inside a $watch

I have a non-isolate scope directive. 我有一个非隔离范围指令。 I don't want to isolate it because it needs to be on elements with other directives. 我不想隔离它,因为它需要与其他指令一起位于元素上。 Yet I need to watch an item on scope. 但是,我需要观看有关范围的项目。 So I tried this: 所以我尝试了这个:

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

This does not work because angular throws a digest cycle already in progress error. 这是行不通的,因为角度抛出一个摘要循环已在进行中错误。 So my question is, how can I dynamically watch an item on scope with a non-isolate directive. 所以我的问题是,如何使用非隔离指令动态观察范围内的项目。

Thanks, 谢谢,

Not entirely sure what your difficulties are watching the item if it is on scope already. 如果项目已经在范围内,则不能完全确定您在观看项目时遇到的困难。 Could you elaborate a bit on this? 您能详细说明一下吗? Regardless, here are two solutions which should cover almost all cases. 无论如何,这里有两种解决方案应涵盖几乎所有情况。 To watch attribute changes, observe the following... 要观看属性更改,请注意以下事项...

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

JSFiddle Link - watch attribute demo JSFiddle Link-观看属性演示


But, I suspect you are having difficulty getting the item on scope. 但是,我怀疑您很难在范围内获得该项目。 If so, here is a way to assign it via $observe then watch it from there without an isolate... 如果是这样,这是一种通过$observe分配它的方法,然后从那里观看它而没有隔离...

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

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

JSFiddle Link - watch attribute demo via $observe JSFiddle Link-通过$observe观看属性演示

You don't want to call $apply inside of a $watch callback because scope.$watch internally calls $apply for you, which is why you are getting the "digest cycle already in progress error" error. 你不想调用$apply一个内部$watch回调,因为scope.$watch内部调用$apply于你,这就是为什么你所得到的错误“正在进行中的错误已经消化周期”。

Instead you can simply do: 相反,您可以简单地执行以下操作:

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

The expression set to myAttribute will get evaluated against the scope of the element on which your directive sits since, like you mentioned, it is not isolated. 设置为myAttribute的表达式将根据指令所在元素的范围进行评估,因为正如您提到的那样,它不是孤立的。 And when the return value changes, the callback function will get invoked. 当返回值更改时,将调用回调函数。

For example, if your HTML looked something like this 例如,如果您的HTML看起来像这样

<div myNoNewScopeDirective myAttribute="doThis(value)"></div>

doThis(value) will get evaluated against the scope associated with the div element and its return value will be watched by your myNoNewScopeDirective . doThis(value)将针对与div元素关联的范围进行评估,并且其返回值将由myNoNewScopeDirective As a result, any change to such value will trigger the callback you provided and when val is truthy, doSomething will get invoked. 结果,对该值的任何更改将触发您提供的回调,并且当val为true时,将调用doSomething

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM