如何替换knockoutjs中的给定索引元素

时间:2011-06-21 12:43:52

标签: knockout.js

如何用另一个元素替换observableArray中的给定索引。

我有: ViewModel.Elements()[index]

如何用其他元素替换它。

5 个答案:

答案 0 :(得分:38)

observableArrays确实有replace方法。这将接收旧项目和新项目。

所以,你会称之为:

ViewModel.Elements.replace(ViewModel.Elements()[index], yourNewElement);

在内部,这只是将索引设置为您的新项目,并调用valueHasMutated()来通知任何潜在订阅者。

答案 1 :(得分:10)

现在已经有点晚了,但我注意到这个问题仍未得到解答(正确)。

正如其他人所述,第一个答案没有给出预期的行为,它会将observableArray的项目替换为value而不是index

其他答案过于复杂,并没有利用Knockout的扩展本地人。


要真正替换index的给定observableArray中的值,您应该使用splice()方法。

var myObservable = ko.observableArray([1, 2, 3, 4]);
myObservable.splice(0, 1, 100); // Replace the value at [0] with "100"
myObservable.splice(2, 1, 300); // Replace the value at [2] with "300"
console.log(myObservable()); // [100, 2, 300, 4]

由于splice()方法由Knockout扩展,它会自动通知任何依赖项,无需调用valueHasMutated()

编辑/ 2016年2月14日

如果您需要一次替换多个值,它可以更快地获取基础数组,执行替换然后通知更改。

var myObservable = ko.observableArray([1, 2, 3, 4]);
var underlyingArray = myObservable();

myObservable.valueWillMutate();

for(...)
   underlyingArray[i] = newValue[i];

this.valueHasMutated();

答案 2 :(得分:5)

就像dvijaz正确指出的那样,接受的答案取代了给定的值。当给定值在数组中不唯一时,这可能会导致问题。

而不是切割数组然后将数组粘合在一起,我做了以下更可读的恕我直言:

ViewModel.Elements()[index] = yourNewElement;
ViewModel.Elements.valueHasMutated();

感谢RP Niemeyer指出.replace内部如何运作。

您还可以扩展observableArray以支持此功能:

ko.observableArray.fn.replaceIndex = function(index, newValue) {
    this.valueWillMutate();
    this()[index] = newValue;
    this.valueHasMutated();
};

这意味着您可以执行以下操作:

var arr = ko.observableArray([1, 2, 1, 4]);
arr.replaceIndex(2, 3); 
console.log(arr()); // logs [1, 2, 3, 4]

答案 3 :(得分:4)

问题是如何替换给定索引"而不是给定值。当observableArray中没有重复时,接受的答案有效,但是如果有重复,那么它将不会总是按预期运行。例如。假设我们有:

index = 2;
elements = ko.observableArray([9,8,9]);

然后我们使用接受的答案。

elements.replace(elements()[index], 7);

然后elements将是[7,8,9](因为replace使用indexOf,它找到给定值9的最低索引),而问题肯定是期望一个使elements[9,8,7]的解决方案。

要真实替换{oborableArray newElementindex处的elements项,您可以使用以下内容。

elements(elements.slice(0, index).concat(newElement, elements.slice(index + 1)));

更优雅的东西会很好。虽然IIUC是一个可读性问题而不是性能问题。

答案 4 :(得分:0)

编辑底层数组并重新分配它对我来说很有用。我在使用其他方法时遇到了麻烦。

var underlyingArray = this.someObservableArray();

// Do modifications... Swap some items...
// No one is being notified just yet...

// Reassign to observable to update everything
this.someObservableArray(underlyingArray);