使用Backbone Relational实现多对多关系



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

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

我最终以我想要的方式完成了这项工作。多对多关系在数据库中维护,但这些关系只能在我的主干模型中从一个方向访问。我决定Person模型将是独立的,PersonGroup模型将有一组对它们所链接的Person模型的引用。

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

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

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,因此更改跟踪会在整个应用程序中传播。

这个问题大约有两个月大了,不过我想告诉大家,在使用Backbone关系时,我遇到了类似的多对多关系问题。这些问题导致编写了自己的主干关系实现,该主干关系支持多对多关系,而两者之间没有链接模型:骨干JJ关系

我是作为作者之一回答的,但这可能值得一看
例如,您在问题中发布的JSON将以以下方式自动反序列化:
每个PeopleGroups-模型都有一个属性People,它是一个骨干。集合包含适当的People-模型,(当然)反之亦然,因此可以很容易地从两侧访问关系(无需链接模型)
Backbone JJRelational的一些概念类似于Backbone relational(例如,全局模型存储)。

相关内容

  • 没有找到相关文章