7

Personaと aの 2 つのクラスを定義する単純なアプリケーションPersonGroupがあり、多対多の関係が存在します。Person は、グループを持たないことも、すべてのグループに割り当てられることも、その間のすべてのグループに割り当てられることもできます。

backbonerelational.org の例では、多対多の関係に中間モデルを使用することを提案していますが、このパターンをフェッチ (逆シリアル化) と保存 (シリアル化) で機能させることはできません。

私がやりたいことは、Backbone を使用して、次のような JSON を逆シリアル化することです。

{
    People:
    [
        {
            "ID": 1,
            "Name": "John"
        },
        {
            "ID": 2,
            "Name": "Bob"
        },
        {
            "ID": 3,
            "Name": "Tim"
        },
    ],
    PeopleGroups:
    [
        {
            "ID": 1,
            "Name": "Owners",
            "People":
            [
                1,
                2
            ],
        },
        {
            "ID": 2,
            "Name": "Everyone",
            "People":
            [
                1,
                2,
                3
            ],
        },
    ]
}

データ バインディングに Knockback/Knockout を使用しているため、問題は参照によって関係にアクセスできる必要があることです。Knockback.CollectionObservable を作成してコレクションをラップし、ID を参照に解決できない限り、ID の配列は何の役にも立ちません。

4

2 に答える 2

8

私はこれを私が望むように動作させることになりました。多対多の関係はデータベースで維持されますが、関係はバックボーン モデルで一方向にしかアクセスできません。Person モデルはスタンドアロンで、PersonGroup モデルはリンク先の Person モデルへの参照のコレクションを持つことにしました。

ここですべてを機能させるための重要なポイントは、 を指定includeInJSON: "ID"して削除することでしたreverseRelation。これでも JavaScript のモデルへの参照にアクセスできますが、JSON に正しくシリアル化および逆シリアル化されます。Person モデルは、所属するグループへのナビゲーション プロパティにアクセスできませんが、複数のグループに存在することは問題ありません。

ID のリストを使用すると、フープを介してジャンプして参照を解決する必要があると単純に想定していましたが、バックボーン リレーショナルは、グローバル バックボーン モデル ストアを使用して、重複したモデルを作成せずに ID で参照を解決しているようです。(例: 3 つの異なるグループが同じ人物を参照でき、作成されるモデルは 1 つだけです)。

var Person = Backbone.RelationalModel.extend(
{
    idAttribute: "ID",
});

var PersonGroup = Backbone.RelationalModel.extend(
{
    idAttribute: "ID",

    relations:
    [
        {
            type: Backbone.HasMany,
            key: "People",
            relatedModel: "Person",
            collectionType: "PersonCollection",
            includeInJSON: "ID",
        },
    ],
});

Backbone.Collections を次のように定義し、個別の API リクエストを介して取得できます。

var PersonCollection = Backbone.Collection.extend(
{
    model: Person,

    url: "/api/person",
});

var PersonGroupCollection = Backbone.Collection.extend(
{
    model: PersonGroup,

    url: "/api/persongroup",
});

var PersonModels = new PersonCollection();

var GroupsModels = new PersonGroupCollection();

this.PersonModels.fetch();

this.GroupsModels.fetch();

this.People = kb.collectionObservable(
    this.PersonModels,
    {
        factories:
        {
            "models": PersonViewModel,
        },
    }
);

this.PersonGroups = kb.collectionObservable(
    this.GroupsModels,
    {
        factories:
        {
            "models": PersonGroupViewModel,
            "models.People.models": PersonViewModel,
        },
    }
);

Knockout.js バインディングを使用するための Knockback.js 固有のコレクションを含めました。モデルごとに 1 つの ViewModel のみが作成されるため、変更の追跡はアプリ全体に伝達されます。

于 2013-07-23T16:11:07.247 に答える
4

この質問は約 2 か月前のものですが、バックボーン リレーショナルを使用しているときに、多対多の関係に関して同様の問題に遭遇したことを共有したいと思います。これらの問題により、間にリンク モデルを介さずに多対多の関係をサポートするバックボーン リレーションの独自の実装が作成されました

私は著者の一人として回答していますが、チェックする価値があるかもしれません。 たとえば、質問に投稿したJSONは
、次の方法で自動的に逆シリアル化されます。両側から簡単にアクセスできます (リンク モデルなし)。 Backbone-JJRelational の一部の概念は、Backbone-relational と似ています (グローバル モデル ストアなど)。
PeopleGroupsPeoplePeople

于 2013-09-19T21:48:22.527 に答える