当项目不可观察时刷新observableArray

use*_*905 29 knockout.js

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

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

Art*_*kov 56

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

yourArray.valueHasMutated();
Run Code Online (Sandbox Code Playgroud)

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

self.refresh = function(){
    var data = self.array().slice(0);
    self.array([]);
    self.array(data);
};
Run Code Online (Sandbox Code Playgroud)

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

  • 为什么需要通过调用slice(0)来复制数组?以下工作也是如此,甚至更好`var data = self.array(); self.array(null); self.array(data);` (9认同)
  • 在处理数组时,Knockout确实是一个POS.为什么它不能更像Angular - 即工作!? (4认同)
  • valueHasMutated对我来说很好. (2认同)

Jot*_*aBe 21

当你有一个带有不可观察元素的可观察数组,并且数组中某个元素的某些属性发生变化时,如果你只想刷新那个元素,你可以使用indexOfsplice,如下所示:

var changedIdx = obsArray.indexOf(changedItem);
obsArray.splice(changedIdx , 1); // removes the item from the array
obsArray.splice(changedIdx , 0, changedItem); // adds it back
Run Code Online (Sandbox Code Playgroud)

这样做,是在数组中查找元素,删除它,然后将其插回.当它被插回时,元素再次与新值绑定.

如果你喜欢这个解决方案,你可以扩展所有ko可观察数组的功能,如下所示:

ko.observableArray.fn.refresh = function (item) {
    var index = this['indexOf'](item);
    if (index >= 0) {
        this.splice(index, 1);
        this.splice(index, 0, item);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,当您更改数组的项目时,您只需进行此调用:

obsArray.refresh(changedItem);
Run Code Online (Sandbox Code Playgroud)

如果你的数组中有许多元素,那么dirtyArtem Vyshniakov 的刷新将提高性能,它会更新数组中所有元素的绑定,而不仅仅是更改后的元素.

注意:valueHasMutatedappart来自未记录(以及内部使用,我想),只检查数组本身是否已更改,而不是数组中的不可观察元素是否已更改,因此它不起作用.即它只检测您是否已向数组添加元素,从数组中删除元素,使用新的不同元素更改数组的元素,或更改元素的顺序.但它不会检查元素本身是否已经改变


MrB*_*MrB 5

我最终使用了上面的脏方法,但是使得我的所有可观察数组都具有此功能.

ko.observableArray.fn.refresh = function () {
        var data = this().slice(0);
        this([]);
        this(data);
    };
Run Code Online (Sandbox Code Playgroud)

valueHasMutated对我不起作用.它有点蹩脚,整个清单必须更新.或者在我的情况下找到一种方法来扩展ko映射插件以用可观察对象填充可观察数组.

  • `var data = this()/*.tickment()*/; this(null); this(data);`也可以工作,甚至更快 (2认同)