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.myItems=getItems(数据);
//您需要在某个地方更新myItems,这并不容易
<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
数据中的内容发生更改。