基本的に、observableArray があり、各項目の値は観察可能ではありません。これは、アイテムの値を変更しても、observableArray の foreach ループ内の UI がそれに応じて更新されないことを意味します。
それらを監視可能に設定する必要がある場合、大幅な変更を意味するため、UI または observableArray foreach を手動で更新する方法はありますか?
基本的に、observableArray があり、各項目の値は観察可能ではありません。これは、アイテムの値を変更しても、observableArray の foreach ループ内の UI がそれに応じて更新されないことを意味します。
それらを監視可能に設定する必要がある場合、大幅な変更を意味するため、UI または observableArray foreach を手動で更新する方法はありますか?
valueHasMutated
はい、配列の関数を呼び出すことができます:
yourArray.valueHasMutated();
編集:最初に「ダーティ」リフレッシュを行うことができなかった場合:
self.refresh = function(){
var data = self.array().slice(0);
self.array([]);
self.array(data);
};
ここにフィドルが働いています:http://jsfiddle.net/vyshniakov/FuEy6/2/
観測不可能な要素を持つ観測可能な配列があり、配列内の要素の 1 つのプロパティが変更された場合、その要素のみを更新したい場合は、次のようにindexOf
andを使用できます。splice
var changedIdx = obsArray.indexOf(changedItem);
obsArray.splice(changedIdx , 1); // removes the item from the array
obsArray.splice(changedIdx , 0, changedItem); // adds it back
これが行うことは、配列内の要素を探し、削除し、挿入し直すことです。挿入し直すと、要素は新しい値で再度バインドされます。
このソリューションが気に入った場合は、次のようにすべての ko オブザーバブル配列の機能を拡張できます。
ko.observableArray.fn.refresh = function (item) {
var index = this['indexOf'](item);
if (index >= 0) {
this.splice(index, 1);
this.splice(index, 0, item);
}
}
次に、配列の項目を変更するときは、次の呼び出しを行うだけです。
obsArray.refresh(changedItem);
配列に多くの要素がある場合dirty
、変更された要素だけでなく、配列内のすべての要素のバインディングを更新する Artem Vyshniakov による更新に関して、パフォーマンスが向上します。
注: はvalueHasMutated
、文書化されていないことを除けば (そして内部使用のためだと思います)、配列内の観測不可能な要素が変更されたかどうかではなく、配列自体が変更されたかどうかのみをチェックするため、機能しません。つまり、配列に要素を追加したか、配列から要素を削除したか、配列の要素を新しい別の要素に変更したか、要素の順序を変更したかのみを検出します。ただし、要素自体が変更されたかどうかはチェックしません
上記の汚いアプローチを使用することになりましたが、すべての監視可能な配列がこの機能を持つようにしました。
ko.observableArray.fn.refresh = function () {
var data = this().slice(0);
this([]);
this(data);
};
valueHasMutated はうまくいきませんでした。リスト全体を更新する必要があります。または、私の場合、ko マッピング プラグインを拡張して、監視可能な配列を監視可能なオブジェクトで埋める方法を見つけてください。
配列内のオブジェクト全体を置き換えることで、簡単な解決策を見つけました。
この例では、パラメーターixはインデックス、oLineは更新されたオブジェクト、oVM.objProps.linesには配列が含まれています。ソリューションはチャンピオンのように機能しました。
/* This contortion causes the computed function to fire because
* we have replaced the entire line object.
*/
function forceRefresh(ix,oLine) {
var oVM = pme.getVM();
oLine = JSON.parse(JSON.stringify(oLine));
oVM.oObjProp.lines[ix] = oLine;
}