Javascript 如何强制ngRepeat不通过引用进行比较?

Javascript 如何强制ngRepeat不通过引用进行比较?,javascript,angularjs,angularjs-ng-repeat,Javascript,Angularjs,Angularjs Ng Repeat,在指令中,我使用从作用域上的参数化函数获取其项的 以简化的方式,它如下所示: <div data-ng-repeat="data in containerItems"> <div data-ng-repeat="myItem in getItems(data) track by myItem.Id"> <!-- some content --> </div> </div> $scope.getItems

在指令中,我使用从作用域上的参数化函数获取其项的

以简化的方式,它如下所示:

<div data-ng-repeat="data in containerItems">
    <div data-ng-repeat="myItem in getItems(data) track by myItem.Id">
        <!-- some content -->
    </div>
</div>
$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
            };
        });
    }
};
但我也试过类似的方法

track by myItem.Id
我曾希望这将迫使
ngRepeat
假定只有在ID更改时才更改项目。然而,所有这些似乎都无法阻止上述异常的发生

<强>是否有任何方法可以迫使angurjs只考虑“代码> NGRIPEAT< <代码>中的一个项目,当它的值发生变化时,而不是实例< <强> >/P> 从结构上看,

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


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

<div data-ng-repeat="data in containerItems">
    <div data-ng-repeat="myItem in getItems(data) track by myItem.Id">
        <!-- some content -->
    </div>
</div>
$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
            };
        });
    }
};

这里的细节不相关。重要的一点是,我根据参数
data
中的某些内容从其他地方检索项目,然后这些项目的格式可能需要转换为规范格式,由我的
ngRepeat
-ed模板处理。

因此,我知道您有一个复杂的机制来获取数据,您需要在大量的
ng repeat
之间共享

由于脏检查与angularJS的工作方式(simple==介于hold值和$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];
};
  • 如果
    getItems(data)
    从未更改,则可以使用一次性绑定:
    ng repeat=“a in::getItems(data)”
  • 如果它发生了变化,您应该将其存储在$scope中并手动更新——这可能是最好的方法。在ng repeat中使用方法是一种糟糕的风格,很可能会在以后导致性能问题。所以,这看起来像:
  • 
    $scope.myItems=getItems(数据);
    
    //您需要在某个地方更新myItems,这并不容易
  • 您的问题是getItems不应该创建对象,所以您可以通过缓存对象或完整结果(请参见Deblaton答案)来修复它,但这通常是不好的。因此,这看起来像:

    <div data-ng-repeat="myItem in getItems(data) track by myItem.Id">
    
    $scope.objectCache = {};
    $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) {
                if (!objectCache[si.code]) { 
                    objectCache[si.code] = {
                       Id: si.code,
                       Name: si.Description + ' ' + si.Owner
                    }; 
                }
                return objectCache[si.code];
            });
        }
    };
    
    
    $scope.objectCache={};
    $scope.getItems=函数(数据){
    var itemSet=itemSets[data.itemSetId];
    if(itemSet.customItems){
    returnitemset.customItems.slice(1);
    }否则{
    返回映射(standardItems.slice(1),函数(si){
    如果(!objectCache[si.code]){
    objectCache[si.code]={
    Id:si.code,
    名称:si.Description+''+si.Owner
    }; 
    }
    返回objectCache[si.code];
    });
    }
    };
    

  • 能否添加函数
    getItems()
    ?使用ng repeat时,确实应该使用不可变表。链接的注释将首先按引用检查,然后按值检查。没有办法只凭价值来做。@DeblatonJean-Philippe:Done,添加了一个
    getItems
    的示例。等等,2(“可能是最好的方法”)和3(“一般来说没有好处”)有何不同?你的意思是我不应该使用以不同格式提供数据的数据源?嗯,事情就是这样;我无法控制来自其他组件的数据是如何形成的。一次性绑定是最好的选择(比我的好)。但是,关于OP需要一个方法来获取其数据,3优于2;-)“在某个地方你需要更新myItems——这不容易”——有点,是的。基本上,我需要在两次执行
    之间更新
    myItems
    ,这两次执行将使用不同的
    myItems
    ,并且彼此相邻显示。@O.R.Mapper No,如果您有两个不同的getItems(1),getItems(2)->您应该在范围内有myItems1,myItems2。我指的是其他一些看起来相当粗糙的变化(为什么缓存一些可以不用任何努力就能计算出来的东西),但如果我的名义问题的直接答案是“你不能”,那么我似乎不得不走这条路。稍后我会接受,以防出现另一个更好的解决方案。@O.R.Mapper我希望您在接受我的回答之前尝试
    。@O.R.Mapper您的组件对于演示组件来说可能太大了。您可能可以将代码拆分为子组件以提高清晰度。该组件由其他人编写,并在应用程序中的不同位置使用。我正在仔细地尝试在不破坏其他部分的情况下编织一个新特性,因此大规模的重组可能是不可行的。话虽如此,在我的原始示例中,我缩短为
    的部分已经在调用我们的一些其他指令。至于
    ::
    ,这似乎不起作用:当
    数据中的某些内容发生更改时,
    getItems
    的结果会发生更改,如果我编写
    ::getItems(data)
    ,则,
    ngRepeat
    不再重新评估
    getItems
    数据中的内容发生更改。