如何用另一个元素替换observableArray中的给定索引。
我有:
ViewModel.Elements()[index]
如何用其他元素替换它。
答案 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()
。
如果您需要一次替换多个值,它可以更快地获取基础数组,执行替换然后通知更改。
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 newElement
中index
处的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);