[英]Running into infinite digest cycle while binding to function that has $http inside
[英]Using a watch inside a link is causing an infinite digest cycle.
我正在尝试编写将分数与颜色关联的指令。
我已经尝试过了,而Plunker在这里 。 指令本身在这里:
.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
}
})
我有几个问题。
link
函数中执行$watch
。 我正在创建一个无限的摘要循环,这不好。 不过,我仍然不确定为什么。 $elem.removeClass()
,它也无法正常工作-该元素保留了以前拥有的所有类。 什么是正确的方法?
只是使事情正常的建议:
$watch
score
和ptsPossible
因为从相应的属性值加载值后,后者永远不会改变。 您还可以访问$watch
回调函数中的scope
变量。 removeClass()
能正常工作。 同时,您可以在这里尝试removeAttr('class')
。 这是带有建议更改的Plunker 。
您需要使用$watchCollection
而不是$watch
。 您正在将数组传递给$watch
,这是$watchCollection
期望的。
正如@miqid所说,无需同时监视score和ptsPossible,因为您只想在得分变化时做出反应(至少在这种情况下会出现)。
这里的问题是您正在使用jqLite的removeClass函数而不是jQuery的 removeClass函数。 如果代码中没有在Angular之前包含jQuery,则Angular会改用jqLite函数,这类似于较小,更简单的jQuery版本。 它也略有不同。 jQuery的removeClass() ,将删除所有没有传递参数的类。 jqLite不会做相同的事情,只会删除您作为参数传递的那些类。
您根本没有包含jQuery,因此就是这种情况。 这是经过编辑的“ Plunker” 。 您可以检查jQuery现在是否包含在顶部,并且一切正常。 而且$ watch更简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.