我正在尝试编写一个将分数与颜色相关联的指令。
我已经尝试了,而且Plunker是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
}
})
我有几个问题。
$watch
函数中执行link
。我正在创造一个无限的消化周期,这并不好。不过,我仍然不确定原因。$elem.removeClass()
,它也不起作用 - 该元素保留了以前的任何类。这样做的正确方法是什么?
答案 0 :(得分:1)
只是建议让事情顺利进行:
$watch
和score
都不需要ptsPossible
,因为后者在从相应的属性值加载值后永远不会更改。您还可以访问scope
回调函数中的$watch
个变量。removeClass()
能够正常工作。你可以在此同时尝试removeAttr('class')
。这里有一个Plunker,其中包含建议的更改。
答案 1 :(得分:1)
您需要使用$watchCollection
而不是$watch
。您将数组传递给$watch
,这是$watchCollection
期望的结果。
答案 2 :(得分:1)
正如@miqid所说,没有必要同时观察得分和ptsPossible,因为你只想在得分发生变化时作出反应(至少在这种情况下你会提出)。
这里的问题是,你使用 jqLite的 removeClass函数而不是 jQuery的。如果在代码中Angular之前没有包含jQuery,Angular将使用jqLite函数,这就像一个更小,更简单的jQuery版本。它也略有不同。 jQuery的 removeClass(),将删除所有类都没有参数传递。 jqLite不会这样做,它只会删除你作为参数传递的那些类。
你根本就没有包含jQuery,所以这就是正在发生的事情。这是经过编辑的Plunker。您可以检查jQuery现在包含在顶部,一切都按预期工作。 $ watch也更简单。