试图了解角度滤镜的本质。所以我有这个:
<p>RandomCase: {{ aString | randomCase }}</p>
和此:
.filter 'randomCase', () ->
(input) ->
input.replace /./g, (c) ->
if Math.random() > 0.5 then c.toUpperCase() else c
Coffeescript在这里制作了一个更干净的代码,在JSFiddle中找到了JS版本以及完整的例子:
http://jsfiddle.net/nmakarov/5LdKV/
重点是通过随机字母大写来装饰字符串。
它有效,但抛出了#$ 10 $ digest()迭代。中止&#34!;大多数时候。我认为由于某种原因,Angular会重新运行过滤器至少两次以查看输出是否相同。如果没有,将再次运行直到最后两场比赛。实际上,由于过滤器的代码产生随机字符串,因此它不太可能连续两次重复。
现在提出一个问题:是否有可能告诉Angular不要多次重新运行此过滤器?我不需要在代码中观察此过滤输出的值,因此不需要Angular来观察更改 - 即使是硬编码的&#34;字符串&#34;用来代替aString
变量,代码行为相同 - 达到了10次迭代......
而且我知道我可以将randomizing
逻辑放在一个控制器中并将结果绑定到$ scope.aString并且它可以正常工作 - 我试图理解Angular的过滤方式。
干杯。
答案 0 :(得分:2)
在没有黑客攻击的情况下,无法在监视的表达式中使用非幂等过滤器。这是我能想到的最简单的一个,它会使滤波器具有幂等性......
使用memoizing函数确保后续调用传递相同参数的过滤器返回相同的结果。
使用下划线的示例:
myApp.filter('randomCase', function() {
return _.memoize(function (input) {
console.log("random");
return input.replace(/./g, function(c) {
if (Math.random() > 0.5) {
return c.toUpperCase();
} else {
return c;
}
});
});
});
答案 1 :(得分:1)
过滤器本身仅在评估带有|
运算符(例如someVar | someFilter
)的表达式时运行。 Anuglar's dirty checking导致表达式被多次评估。
简而言之,Angular一遍又一遍地运行表达式aString | randomCase
,直到它没有改变。那时它知道要放入DOM的内容。为了防止在该值不停止更改时无限循环,它会抛出无限$ digest错误。
因此,过滤器始终至少运行两次。一旦获得初始值,然后第二次将其与第一个值进行比较。
通过将随机化逻辑放在控制器中,您可以在HTML中使用{{randomizedString}}
。 randomizedString
的值不会从第一次评估时发生变化,因此可以在不遇到无限$ digest错误的情况下实现最终目标。