基本上我有一个observableArray,每个项目的值都不是可观察的。这意味着当我更改项目值时,observableArray的foreach循环中的UI不会相应地更新。
如果我必须将它们设置为observable,这意味着一个巨大的变化,那么有没有办法可以手动刷新UI或observableArray foreach?
答案 0 :(得分:56)
是的,您可以为您的阵列调用valueHasMutated
函数:
yourArray.valueHasMutated();
编辑: 如果第一次没有帮助你可以做'脏'刷新:
self.refresh = function(){
var data = self.array().slice(0);
self.array([]);
self.array(data);
};
答案 1 :(得分:19)
当您有一个带有不可观察元素的可观察数组,并且数组中某个元素的某些属性发生更改时,如果您只想刷新该元素,则可以使用indexOf
和splice
,像这样:
var changedIdx = obsArray.indexOf(changedItem);
obsArray.splice(changedIdx , 1); // removes the item from the array
obsArray.splice(changedIdx , 0, changedItem); // adds it back
这样做,是在数组中查找元素,删除它,然后将其插回。当它被插回时,元素再次与新值绑定。
如果你喜欢这个解决方案,你可以扩展所有ko可观察数组的功能,如下所示:
ko.observableArray.fn.refresh = function (item) {
var index = this['indexOf'](item);
if (index >= 0) {
this.splice(index, 1);
this.splice(index, 0, item);
}
}
然后,当您更改数组的项目时,您只需进行此调用:
obsArray.refresh(changedItem);
如果阵列中有许多元素,那么Artem Vyshniakov对dirty
刷新的性能会有所改善,它会更新阵列中所有元素的绑定,而不仅仅是换了一个。
注意:valueHasMutated
,appart来自未记录(以及内部使用,我猜),只检查数组本身是否已更改,而不是数组中的非可观察元素是否已更改,所以它不起作用。即它只检测您是否已向数组添加元素,从数组中删除元素,使用新的,不同的元素更改数组的元素,或更改元素的顺序。但它没有检查元素本身是否已经改变
答案 2 :(得分:5)
我最终使用了上面的脏方法,但是它使我的所有可观察数组都具有此功能。
ko.observableArray.fn.refresh = function () {
var data = this().slice(0);
this([]);
this(data);
};
valueHasMutated对我不起作用。它有点蹩脚,整个清单必须更新。或者在我的情况下找到一种方法来扩展ko映射插件以用可观察对象填充可观察数组..
答案 3 :(得分:0)
我通过替换数组中的整个对象找到了一个简单的解决方案。
在此示例中,参数 ix 是索引, oLine 是更新的对象, oVM.objProps.lines 包含数组。解决方案就像一个冠军。
/* This contortion causes the computed function to fire because
* we have replaced the entire line object.
*/
function forceRefresh(ix,oLine) {
var oVM = pme.getVM();
oLine = JSON.parse(JSON.stringify(oLine));
oVM.oObjProp.lines[ix] = oLine;
}
答案 4 :(得分:0)
我将Knockout与deferUpdates一起使用,而JotaBe的解决方案需要更新。
似乎Knockout在删除/添加时检测到同一项目,因此不要刷新数组。
我采用了以下解决方案:
Button
并正确刷新数组! : - )
注意我为刷新函数添加了第二个参数,用于在给定索引时指定索引,以避免indexOf运行。