1

Knockout.js の使用:

アイテム/オブジェクトが複数の場所 (まったく同じオブジェクト) のビューモデル内にある場合、ユーザーが 1 つの場所でアイテムを編集すると、他のアイテムが次のように自動的に更新されるように、両方のアイテムを一緒にバインドすることは可能ですか?良い?

例: http://jsfiddle.net/77Jc5/1/

var model = {
    Foo : [
        {
            ID: 99,
            Title: 'This is item number ninety-nine',
            Description: 'This is an item included in more than one object'
        },
        {
            ID: 100,
            Title: 'This is item number one-hundred',
            Description: 'This is an item included in only one object'
        }
    ],
        Poo : [
        {
            ID: 99,
            Title: 'This is item number ninety-nine',
            Description: 'This is an item included in more than one object'
        }
    ]
};

この例では、ユーザーが Foo または Poo のいずれかでアイテム #99 を編集すると、両方で変更したいと思います...できればユーザーが変更しているとき (キープレス イベント?)。

ソリューション

モデルは次のようになります。

var model = {
    AllMembers: [
        { ID: 100, Title: 'This is item number 100' },
        { ID: 776, Title: 'This is item number 776' },
        { ID: 456, Title: 'This is item number 456' },
        { ID: 999, Title: 'This is item number 999' }
    ],
    Foo: [],
    Poo: []
};

解決策 1: (@Joseph Gabriel の功績)

http://jsfiddle.net/lamarant/hMutz/8/

このソリューションでは、Foo および Poo 配列にオブジェクトの重複したインスタンスが含まれます。Knockout は、オブジェクト間の同期を処理します。これは機能しますが、ビュー モデル全体でデータが複製されるため、アーキテクチャの観点からは理想的ではありません。

解決策 2: (@Jeff Mercado の功績)

http://jsfiddle.net/jeff1203/rndM9/2/

このソリューションでは、Foo および Poo 配列には、参照されるオブジェクトの ID のみが含まれます。アーキテクチャ的には、これが正しい方法だと思いますが、より多くのコードが必要になります。

これを読んでいる場合、1 日の終わりには、おそらくビュー モデルを処理のためにサーバーに投稿することになるでしょう。これには、モデルをデータベースに保存することが必要になるでしょう。どちらのソリューションも、データベースに存在する 1 対多の関係を適切に処理します。私の要件では、連続した負の値を ID 番号 (ID: -1、ID: -2 など) として使用して、AllMembers 配列に新しい要素も追加しています。サーバー側の処理シーケンスは次のようになります。

  1. データベース内に新しく作成された ID に対応するデータベースに負の ID をマップする配列を作成します。
  2. AllMembers 配列内のメンバーをループして、データベース内の各メンバーを更新/作成します。新しいメンバーを作成する場合は、その負の ID と新しい ID を手順 1 で作成した配列に追加します。
  3. モデルがその情報のマスターになったため、データベース内の Foo/Poo 間の既存の 1 対多の関係をすべて削除します。
  4. Poo と Foo をループし、モデルから Foo/Poo へのすべての関係を 1-many テーブルに追加します (ID を使用)。

ふぅ…

ノックアウトは素晴らしいです。

4

4 に答える 4

2

心に留めておくべき主なことは、ノックアウトはそれがバインドされているすべてのオブジェクトを更新するということですが、同じオブジェクトを更新可能にし、複数の場所で変更を反映させるためには、単にオブジェクトではなく同じオブジェクトでなければなりません。クローン

同じ名前やプロパティを持つ 2 つのオブジェクトでは十分ではありません。実際には、同じメモリアドレスを指している単一のオブジェクトである必要があり、複数の場所で表示およびバインドできます。

必要なだけ多くの場所から同じ項目を参照できるように、viewModel からデータを分離することを検討します。

var items = [{
    ID: 99,
    Title: 'This is item number ninety-nine',
    Description: 'This is an item included in more than one object'
}, {
    ID: 100,
    Title: 'This is item number one-hundred',
    Description: 'This is an item included in only one object'
}];

var model = {
    Foo : [
        items[0],
        items[1]
    ],
        Poo : [
        items[0]
    ]
};
var viewModel = ko.mapping.fromJS(model);
ko.applyBindings(viewModel);

そうは言っても、ビューモデルに重複した参照を直接持つのは少し厄介なようです。あなたのシナリオが何であるかはわかりませんが、コを使用することは可能でしょうか. あなたに「うんち」値を与えるために計算されますか、またはその逆ですか?

于 2013-04-22T02:16:18.843 に答える
0

次のようなコードを書いた場合:

var num99 = {
            ID: 99,
            Title: 'This is item number ninety-nine',
            Description: 'This is an item included in more than one object'
        };

var model = {
    Foo : [
        num99,
        {
            ID: 100,
            Title: 'This is item number one-hundred',
            Description: 'This is an item included in only one object'
        }
    ],
        Poo : [
        num99
    ]
};

次にFooPoo実際に同じオブジェクトを指すようにして、一方を変更すると他方が変更されるようにします。

jsFiddle の例

于 2013-04-22T00:59:10.500 に答える
0

アーキテクチャの観点から、このようにモデルを複製するべきではないと思います。代わりに「Foo」のみを使用し、複数のビューで使用してください。コードの重複が少なくなり、すべてが自動的に行われ、エラーが発生しにくくなります。

これを行うには、ko.applyBindings()複数の要素で関数を使用できます。

キープレスイベントもある小さな例: http://jsfiddle.net/Z5yGf/2/

于 2013-04-22T01:01:47.240 に答える