2つのビューモデルがあり、それぞれが異なるが類似したデータを表す監視可能なプロパティを持っているとします。
function site1Model(username) {
this.username = ko.observable(username);
....
}
function site2Model(username) = {
this.username = ko.observable(username);
....
}
これらのビューモデルは独立しており、必ずしも相互にリンクされている必要はありませんが、場合によっては、3番目のビューモデルがそれらの間にリンクを作成します。
function site3Model(username) = {
this.site1 = new site1Model(username);
this.site2 = new site2Model(username);
// we now need to ensure that the usernames are kept the same between site1/2
...
}
これが私が思いついたいくつかのオプションです。
一方を読み取り、両方に書き込む計算されたオブザーバブルを使用します。
site3Model.username = ko.computed({ read: function() { return this.site1.username(); // assume they are always the same }, write: function(value) { this.site1.username(value); this.site2.username(value); }, owner: site3Model }
これにより、変更が常に計算によって行われる限り、値の同期が維持されます。ただし、基になるオブザーバブルが直接変更された場合は、変更されません。
このメソッドを使用して、
subscribe
相互に更新します。site3Model.site1.username.subscribe(function(value) { this.site2.username(value); }, site3Model); site3Model.site2.username.subscribe(function(value) { this.site1.username(value); }, site3Model);
これは、値が同じ場合にオブザーバブルが通知を抑制する限り機能します。そうしないと、無限ループになってしまいます。以前にチェックを行うこともできます。これには、オブザーバブルが単純でなければならないという問題もあります(そして、それ自体がオブザーバブルである
if (this.site1.username() !== value) this.site1.username(value);
場合は正しく機能しません)。site1
site2
computed
サブスクライブと更新を行うために使用します。site3Model.username1Updater = ko.computed(function() { this.site1.username(this.site2.username()); }, site3Model); site3Model.username2Updater = ko.computed(function() { this.site2.username(this.site1.username()); }, site3Model);
この形式では、他の依存関係を持つことができます。たとえば、
site1
オブザーバsite2
ブルを作成してから使用することができますthis.site1().username(this.site2().username());
。このメソッドでは、無限ループを回避するために同等性をチェックする必要もあります。オブザーバブルに依存できない場合は、計算内でチェックできますが、更新しているオブザーバブルに別の依存関係を追加します(のようなものobservable.peek
が利用可能になるまで)。この方法には、依存関係を設定するために最初に更新コードを1回実行するという欠点もあります(これがcomputed
機能するため)。
これらの方法にはすべて欠点があると思うので、これを行う別の方法は、単純(10行未満のコード)、効率的(不要なコードや更新を実行しない)、柔軟性(複数レベルのオブザーバブルを処理する)です。 )?