ObservableArray内の特定のインデックスを別の要素に置き換えるにはどうすればよいですか。
私は持っています:ViewModel.Elements()[index]
どうすれば別の要素に置き換えることができますか。
observableArraysにはreplace
メソッドがあります。これは、古いアイテムと新しいアイテムを取り込みます。
だから、あなたはそれを次のように呼ぶでしょう:
ViewModel.Elements.replace(ViewModel.Elements()[index], yourNewElement);
内部的には、これはそのインデックスを新しいアイテムに設定し、valueHasMutated()を呼び出して潜在的なサブスクライバーに通知します。
今では少し遅れていますが、この質問にはまだ(適切に)答えられていないことに気づきました。
他の人が述べているように、最初の答えは期待される動作を与えません。それはobservableArray
のアイテムをvalue
ではなくindex
に置き換えます!
他の答えは非常に複雑で、ノックアウトの拡張ネイティブを利用していません。
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();
_
Dvijazが正しく指摘しているように、受け入れられた回答は指定された値を置き換えます。これは、指定された値が配列内で一意でない場合に問題を引き起こす可能性があります。
配列をスライスしてから接着して戻す代わりに、私は次のことを行いました。これは私見です。
ViewModel.Elements()[index] = yourNewElement;
ViewModel.Elements.valueHasMutated();
方法を指摘してくれたRPNiemeyerに感謝します.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]
質問は、特定の値ではなく、「特定のインデックス」を置き換える方法を尋ねます。受け入れられた回答は、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]
にするソリューションを期待しています。
ObservableArray newElement
のindex
にあるアイテムをelements
に本当に置き換えるには、次を使用できます。
elements(elements.slice(0, index).concat(newElement, elements.slice(index + 1)));
もっとエレガントなものはニースでしょう。 IIUCですが、パフォーマンスではなく読みやすさの問題です。
基になる配列を編集して再割り当てすることで、私はうまくいきました。私は他のアプローチで問題を抱えていました。
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);