当项目不可观察时刷新observableArray

时间:2012-11-05 12:02:34

标签: knockout.js

基本上我有一个observableArray,每个项目的值都不是可观察的。这意味着当我更改项目值时,observableArray的foreach循环中的UI不会相应地更新。

如果我必须将它们设置为observable,这意味着一个巨大的变化,那么有没有办法可以手动刷新UI或observableArray foreach?

5 个答案:

答案 0 :(得分:56)

是的,您可以为您的阵列调用valueHasMutated函数:

yourArray.valueHasMutated();

编辑: 如果第一次没有帮助你可以做'脏'刷新:

self.refresh = function(){
    var data = self.array().slice(0);
    self.array([]);
    self.array(data);
};

这是工作小提琴:http://jsfiddle.net/vyshniakov/FuEy6/2/

答案 1 :(得分:19)

当您有一个带有不可观察元素的可观察数组,并且数组中某个元素的某些属性发生更改时,如果您只想刷新该元素,则可以使用indexOfsplice ,像这样:

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运行。