在指令中,我正在使用ngRepeat,它从范围上的参数化函数获取其项。

以简化的方式,它看起来像这样:

<div data-ng-repeat="data in containerItems">
    <div data-ng-repeat="myItem in getItems(data) track by myItem.Id">
        <!-- some content -->
    </div>
</div>


我的问题是我似乎无法摆脱以下异常:


  错误:[$ rootScope:infdig]达到10个$ digest()迭代。流产!


据我根据其他几个问题(例如thisthis)得出的结论,ngRepeat似乎认为每次重新请求项目时都会对其进行更新,从而导致出现另一个摘要循环,最终以过多的连续结尾而放弃。

特别是,用户one commentg00fy对我很有见地:确实,我使用lodash_.map function生成了ngRepeat显示的项目列表,因此每次重新请求其项目。

最初,我认为我可以通过将项目生成函数的返回值保存到示波器上的变量中来解决此问题。这消除了上面的错误。

不幸的是,这对我来说不是一个合适的解决方案,因为范围由使用ngRepeat的我的指令的多个实例共享。我真的需要每个ngRepeat使用适当的参数从生成函数中检索项目。

起初,我在使用

track by $index


但我也尝试过类似

track by myItem.Id


我希望这将迫使ngRepeat假定仅当ID更改时项目才更改。但是,这似乎都不能阻止上述异常的发生。

有什么办法可以迫使AngularJS仅在ngRepeat中的值更改时考虑更改的项目,而不是实例?

从结构上讲,似乎ngRepeat的返回值可以保存在getItems(data)上。但是,我正在处理的应用程序框架中的代码(这意味着它依赖于该应用程序的许多模块的行为,因此不能更改)将直接采用包含data的对象图并发送到服务器端后端。因此,data不是计算的运行时数据的正确位置。



为了提供更完整的示例,data函数大致如下所示:

$scope.getItems = function (data) {
    var itemSet = itemSets[data.itemSetId];
    if (itemSet.customItems) {
        return itemSet.customItems.slice(1);
    } else {
        return _.map(standardItems.slice(1), function (si) {
            return {
                Id: si.code,
                Name: si.Description + ' ' + si.Owner
            };
        });
    }
};


这里的细节无关紧要。重要的部分是,我根据参数getItems中的内容从其他位置检索项目,然后这些项目的格式可能需要转换为由我的data版本模板处理的规范格式。

最佳答案

因此,我了解您有一个复杂的机制来获取数据,您需要在许多ng-repeat之间共享。

因为脏检查的方式是与angularJS一起使用的(保持值和$ scope值之间的简单===),所以您必须将ng-repeat分配给单个引用(如果更新了集合,则使用不可变的对象)。

您为什么不能执行以下操作来获取数据?

myItems = {};
$scope.getItems = function (data) {
    if(!myItems[data.itemSetId]) {
        var itemSet = itemSets[data.itemSetId];
        if (itemSet.customItems) {
            myItems[data.itemSetId] = itemSet.customItems.slice(1);
        } else {
            myItems[data.itemSetId] _.map(standardItems.slice(1), function (si) {
                return {
                    Id: si.code,
                    Name: si.Description + ' ' + si.Owner
                };
            });
        }
    }
    return myItems[data.itemSetId];
};

07-26 02:05