34

我正在尝试observableArray用新内容替换项目的所有内容。

var oldLocation = ko.utils.arrayFirst(self.locations(), function (item) {
    return item.id == value.id;
});
self.locations.replace(self.locations.indexOf(oldLocation), new location(value));
self.locations.valueHasMutated();

我也试过

self.locations[self.locations.indexOf(location)] = new fizi.ko.models.location(value);

但没有任何工作。正在正确检索索引,但没有更新项目。

4

3 回答 3

52

replace 函数接受两个参数,要替换的项目和要替换的新项目。您正在传递索引来代替要替换的项目,因此它不起作用。

替换调用应该是:

self.locations.replace(oldLocation, new location(value));

附带说明一下,您不需要在valueHasMutated()那里调用,它将被调用replace()调用。


旁注,许多原生 Array 函数可用于可观察数组。它们被转发到底层数组值,根据需要触发突变通知。这些包括:

pop, push, reverse, shift, sort, splice, unshift, slice(只读)。

Knockout 提供了这些应在此处记录的附加方法(当前为 v3.5.1):

remove, removeAll, destroy, destroyAll, indexOf, replace, sorted,reversed

于 2013-03-15T19:49:27.507 回答
4

我只想提一种替代方法:

self.locations.splice(
  self.locations.indexOf(location),   // Index of the 1st element to remove
  1,                                  // Number of elements to remote at this index
  new fizi.ko.models.location(value)  // A param for each element to add at the index
);

Knockout 包含splice在其文档中,但不包括replaceKnockout Obervable Arrays Docs。但是,如果您查看源代码,您会发现这两个功能都实现了(至少在 KO 3.0 中,我不知道replace在以前的版本中是否缺少)。

于 2015-01-05T12:23:57.427 回答
3

我不知道 JavaScript 中数组或 Knockout 中的替换方法。我错过了什么吗?

如果您想使用第二种方法,那么您需要以可观察的形式访问位置:

self.locations()[self.locations.indexOf(location)] = new fizi.ko.models.location(value);
self.locations.valueHasMutated();

虽然你在使用 indexOf 时不这样做,因为有一个用于可观察数组的 Knockout 版本。

于 2013-03-15T19:48:17.693 回答