angularjs - 非幂等过滤器导致无限 $digest 错误

标签 angularjs angularjs-filter

尝试了解 Angular 过滤器的本质。所以我有这个:

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

还有这个:

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

Coffeescript 在这里提供了更清晰的代码,JS 版本以及完整的示例可以在 JSFiddle 中找到:

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

重点是通过将随机字母大写来修饰字符串。

它可以工作,但会抛出“已达到 10 $digest() 迭代。正在中止!”大多数时候。我认为出于某种原因,Angular 会重新运行过滤器至少两次以查看输出是否相同。如果没有,将再次运行直到最后两场比赛。事实上,由于过滤器的代码生成随机字符串,因此它不太可能连续重复两次。

现在的问题是:是否可以告诉 Angular 不要多次重新运行此过滤器?我不需要在代码中观察此过滤输出的值,因此 Angular 不需要观察更改 - 即使使用硬编码的“字符串”代替 aString 变量,代码的行为相同 - 达到 10 次迭代...

而且我知道我可以将随机化逻辑放入 Controller 中并将结果绑定(bind)到 $scope.aString 并且它会正常工作 - 我正在尝试理解过滤器的 Angular 方式.

干杯。

最佳答案

如果不进行黑客攻击,就无法在监视表达式中使用非幂等过滤器。这是我能想到的最简单的一个,这将使过滤器幂等......

使用内存函数来确保对过滤器的后续调用传递相同的参数返回相同的结果。

使用下划线的示例:

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

Updated Fiddle

关于angularjs - 非幂等过滤器导致无限 $digest 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23939146/

相关文章:

angularjs - 使用下拉列表过滤数据?

javascript - 想要在 Angular 中实现 jquery-ui-daterangepicker

javascript - 在 states.js 中使用多个解析

javascript - 当我下次访问同一个 View 时,如何使用 AngularJS 重用在浏览器中呈现的 View

angularjs - 如何在 Angularjs 模板中访问常量

javascript - 在 ES6 类过滤器中插入服务

angularjs - 默认情况下从选择框中选择第一个值 - AngularJS

javascript - 如何在 Angularjs 中创建过滤器?

angularjs - Angular 广播

javascript - 根据过滤后的输出显示/隐藏警告消息 ng-repeat