非幂等过滤器造成无限$消化错误过滤器、错误

2023-09-14 00:16:30 作者:彼岸之花、开了一夏

试图了解角滤波器的性质。所以我有这样的:

Trying to understand the nature of Angular filters. So I have this:

<p>RandomCase: {{ aString | randomCase }}</p>

和这样的:

.filter 'randomCase', () ->
    (input) ->
        input.replace /./g, (c) ->
            if Math.random() > 0.5 then c.toUpperCase() else c

的CoffeeScript使得清洁code在这里,JS版采用的是与的jsfiddle完整的例子一起找到:

Coffeescript makes for a cleaner code here, JS version is found in JSFiddle along with the complete example:

http://jsfiddle.net/nmakarov/5LdKV/

问题的关键是通过具有随机字母大写来装点一个字符串。

The point is to decorate a string by having random letters capitalized.

它的工作原理,但抛出10 $摘要()迭代达到。中止!大多数时候。我想,因为某些原因角将重新运行过滤器至少两次地看到,输出是相同的。如果没有的话,将再次运行它,直到最后两场比赛。事实上,由于过滤器的code产生一个​​随机字符串,它是不太可能会重演连续两次。

it works, but throws "10 $digest() iterations reached. Aborting!" most of the time. I figured that for some reason Angular would re-run the filter at least twice to see that outputs are the same. And if not, will run it again until the last two matches. Indeed, since the filter's code produces a random string, it is quite unlikely it will repeat itself twice in a row.

现在的问题:是否有可能告诉角度不重新运行该过滤器不止一次?我并不需要观察在code此滤波输出的值,所以没有必要角度看变化 - 即使硬codeD串在地方的使用 ASTRING 变量中,code行为相同 - 10迭代达到...

Now to the question: is it possible to tell Angular not to re-run this filter more than once? I do not need to observe the value of this filtered output in the code, so no need for Angular to watch the changes - even if a hardcoded "string" be used in place of an aString variable, the code behaves the same - 10 iterations reached...

和我知道,我可以把控制器中的随机逻辑和结果到$ scope.aString绑定,这将只是工作 - 我试图了解过滤器的角方式。

And I know that I can put the randomizing logic in a controller and bind the result to a $scope.aString and it would just work - I'm trying to understand the Angular way of filters.

干杯。

推荐答案

有没有办法使用在观看前pression一个非幂等过滤器没有破解。这是我能想到的最简单的一种,这将使得滤波器幂等...

There is no way to use an non-idempotent filter in a watched expression without a hack. This the simplest one that I can think of, which will make the filter idempotent...

使用一个memoizing功能,以确保对过滤器的后续调用传递相同的参数返回相同的结果。

Use a memoizing function to ensure that subsequent calls to the filter passing the same arguments return the same result.

例使用下划线:

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;
            }
        });
    });
});

更新小提琴