7

我有一个简单的应用程序,它定义了两个类 aPerson和 a PersonGroup,其中存在多对多关系。一个人可以没有组,也可以分配给所有组,以及介于两者之间的任何组。

骨干关系.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 进行数据绑定,所以问题是我需要能够通过引用访问关系。一个 ID 数组对我没有任何好处,除非我可以创建一个 Knockback.CollectionObservable 来包装集合并将 ID 解析为引用。

4

2 回答 2

8

我最终让它按照我想要的方式工作。多对多关系在数据库中维护,但只能在我的 Backbone 模型中以一个方向访问这些关系。我决定 Person 模型将是独立的,而 PersonGroup 模型将具有对它们链接到的 Person 模型的引用集合。

这里使一切正常的关键点是指定includeInJSON: "ID"和删除reverseRelation. 这仍然允许您访问对 JavaScript 中模型的引用,但它可以正确地序列化和反序列化为 JSON。Person 模型根本无法访问它们所在的组的导航属性,但是它们可以存在于多个组中就好了。

我只是假设使用 ID 列表将要求跳过箍来解析引用,但 Backbone-relational 似乎使用全局 Backbone 模型存储来通过 ID 解析引用而不创建重复模型。(例如,三个不同的组可以引用同一个 Person 并且只创建一个模型)。

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 特定集合。每个模型只创建一个 ViewModel,因此更改跟踪会传播到整个应用程序。

于 2013-07-23T16:11:07.247 回答
4

这个问题大约有两个月了,但是我想分享一下我在使用 Backbone-relational 时遇到了关于多对多关系的类似问题。这些问题导致编写了自己的 Backbone 关系实现,该实现支持多对多关系,而两者之间没有链接模型: Backbone-JJRelational

我作为作者之一回答,但可能值得一试。
例如,您在问题中发布的 JSON 将通过以下方式自动反序列化:
每个PeopleGroups-model 都有一个属性People,它是一个 Backbone.Collection 包含适当的People-models 和(当然)反之亦然,所以关系可以可以从双方轻松访问(没有链接模型)。
Backbone-JJRelational 的一些概念类似于 Backbone-relational(例如,全局模型存储)。

于 2013-09-19T21:48:22.527 回答