[英]Using a watch inside a link is causing an infinite digest cycle.
I'm trying to write a directive that associates a score with a color. 我正在尝试编写将分数与颜色关联的指令。
I've made an attempt already, and the Plunker is here . 我已经尝试过了,而Plunker在这里 。 The directive itself is here:
指令本身在这里:
.directive('scorebox', function () {
function link ($scope, $elem, $attr) {
var one = 1;
$scope.$watch('[score,ptsPossible]', function (newValue) {
pctScore = newValue[0] / newValue[1]
if (pctScore <= 0.4) {
rating = 'low';
} else if (pctScore <= 0.6) {
rating = 'med';
} else if (pctScore <= 0.8) {
rating = 'high';
} else if (pctScore == 1) {
rating = 'perfect';
}
$elem.removeClass();
$elem.addClass('scorebox');
$elem.addClass(rating);
$elem.text(newValue[0] + "/" + newValue[1]);
});
};
return {
restrict: 'E',
scope: {
score: "=",
ptsPossible: "="
},
link:link
}
})
I've got a couple of problems. 我有几个问题。
$watch
inside a link
function. link
函数中执行$watch
。 I'm creating an infinite digest cycle, and that's not good. $elem.removeClass()
, it's not working--the element retains any classes it had before. $elem.removeClass()
,它也无法正常工作-该元素保留了以前拥有的所有类。 What is the right way to do this? 什么是正确的方法?
Just a suggestion to get things working: 只是使事情正常的建议:
$watch
both score
and ptsPossible
since the latter never changes after the value is loaded from its corresponding attribute value. $watch
score
和ptsPossible
因为从相应的属性值加载值后,后者永远不会改变。 You also have access to scope
variables inside the $watch
callback function. $watch
回调函数中的scope
变量。 removeClass()
to work as well. removeClass()
能正常工作。 You could instead try removeAttr('class')
here in the meanwhile. removeAttr('class')
。 Here's a Plunker with the suggested changes. 这是带有建议更改的Plunker 。
You need to use $watchCollection
and not $watch
. 您需要使用
$watchCollection
而不是$watch
。 You are passing in an array to $watch
which is how $watchCollection
expects. 您正在将数组传递给
$watch
,这是$watchCollection
期望的。
As @miqid said, no need to $watch both score and ptsPossible, since you only want to react when score changes (at least in this situation you are presenting). 正如@miqid所说,无需同时监视score和ptsPossible,因为您只想在得分变化时做出反应(至少在这种情况下会出现)。
The problem here, is you are using jqLite's removeClass function instead of jQuery's . 这里的问题是您正在使用jqLite的removeClass函数而不是jQuery的 removeClass函数。 If jQuery is not included before Angular in the code, Angular will instead use jqLite functions, which is like a smaller, much simpler version of jQuery.
如果代码中没有在Angular之前包含jQuery,则Angular会改用jqLite函数,这类似于较小,更简单的jQuery版本。 It is also, slightly different.
它也略有不同。 jQuery's removeClass() , will remove all classes is no parameter is passed.
jQuery的removeClass() ,将删除所有没有传递参数的类。 jqLite will not do the same, it will just remove those classes that you pass as parameter.
jqLite不会做相同的事情,只会删除您作为参数传递的那些类。
You never included jQuery at all, so that's what's happening. 您根本没有包含jQuery,因此就是这种情况。 Here is the edited Plunker .
这是经过编辑的“ Plunker” 。 You can check jQuery is now included in the top, and everything works as expected.
您可以检查jQuery现在是否包含在顶部,并且一切正常。 And also the $watch is much simpler.
而且$ watch更简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.