【问题标题】:$filter working but resulting in "Error: 10 $digest() iterations reached. Aborting!"$filter 工作,但导致“错误:达到 10 个 $digest() 迭代。中止!”
【发布时间】:2015-12-15 09:09:24
【问题描述】:

所以我有一个看起来有点像这样的 JSON 对象:

{
    "conversations":[
        {
            "_id": "55f1595d72b67ea90d008",
            "topic_id": 30,
            "topic": "First Conversation",
            "admin": "admin@gmail.com",
            "__v": 0,
            "messages": [
                {
                    "body": "Hello?",
                    "timestamp": "2015-09-10T10:20:40.000Z",
                    "from": "admin@gmail.com",
                    "_id": "55f1597a72b67ea90d009"
                }
            ],
            "to": [
                "me@gmail.com"
            ]
        }
    ]
}

我正在尝试创建一个自定义过滤器来查找不同对话中的消息。我需要过滤器来返回与过滤器匹配的对话、消息、发件人和消息的时间戳。

我的自定义过滤器如下所示:

.filter('searchForMessage', function() {
    return function(arr, searchString) {
        if (!searchString) {
            return arr;
        }
        var result = [];
        searchString = searchString.toLowerCase();
        angular.forEach(arr, function(conversation) {
            for (var i = 0; i < conversation.messages.length; i++) {
                if (conversation.messages[i].body.toLowerCase().indexOf(searchString) !== -1) {
                    result.push({
                        conversation: conversation,
                        message: conversation.messages[i].body,
                        from: conversation.messages[i].from,
                        timestamp: conversation.messages[i].timestamp
                    });
                }
            }       
        });
        return result;
    }
});

此过滤器有效,因为它返回了所有正确的数据,但我也收到“错误:已达到 10 个 $digest() 迭代。正在中止!”。

有人知道为什么会这样吗?

任何帮助表示赞赏。

【问题讨论】:

    标签: javascript angularjs angularjs-filter


    【解决方案1】:

    因为您的过滤器每次都会返回新值(当您推送元素时)。 Angular 会发现它不是严格相同的值(=== 比较),并会触发一个新的摘要。

    要解决此问题,您需要不断返回具有完全相同元素的数组。

    【讨论】:

    • 当您说它需要不断返回具有完全相同元素的数组时,我不明白您的意思?那么如果我更新搜索词,过滤器的结果肯定不会更新吗?
    • 我的意思是您的过滤器函数必须是pure function:对于给定的一组输入(您的数据数组和您的搜索查询),您必须始终返回完全相同的输出。当然,您仍然可以为不同的输入返回不同的输出(例如,对于不同的搜索查询)。
    • 但是正常的过滤器肯定每次都会返回新值吗?对不起,我看起来很固执,但我只是在努力解决这个问题。
    • 它们返回不同的数组,但返回相同的对象集。例如,一个有效的过滤器(ES6 语法)是set =&gt; { return set.filter(object =&gt; object.id % 2 === 0) },一个无效的过滤器是set =&gt; { return set.map(object =&gt; object.id); }(因为在第二种情况下,您在每次调用时都会创建新的不同对象,从而触发一个新的摘要循环ad vitam aeternam)。简而言之:只使用过滤器过滤数据,而不是创建或修改现有的。
    最近更新 更多