【问题标题】:Ember Data - Polymorphic relationshipsEmber 数据 - 多态关系
【发布时间】:2015-02-14 16:41:02
【问题描述】:

我刚刚偶然发现了 Ember 数据多态关系。我认为它们对我的工作很有用。这是我的主要模型。该模型定义了与异步和多态的主题有很多关系。

App.Source = DS.Model.extend({
    name: DS.attr('string'),
    type: DS.attr('string'),
    locationType: DS.attr('string'),
    locationSpecific: DS.attr('boolean'),
    primary: DS.attr('boolean'),
    published: DS.attr('boolean'),
    sort: DS.attr('number'),
    topics: DS.hasMany('topic', {
        async: true,
        polymorphic: true
    })
});

接下来我们有一个基类为“主题”的主题

App.Topic = DS.Model.extend({
    name: DS.attr('string'),
    sort: DS.attr('number'),
    source: DS.belongsTo('source')
});

App.RegTopic = App.Topic.extend({
    test: DS.attr('number', {
        defaultValue: 8
    }),
    notes: DS.hasMany('notes', {
        async: true
    })
});

App.SummaryTopic = App.Topic.extend({
    number: DS.attr('number', {
        defaultValue: 9
    })
});

这是我获取主题的方法

App.TopicsRoute = Ember.Route.extend({
     model: function() {
           return this.modelFor('source').get('topics');
     }
});

当我列出来源时,我会得到以下对象的列表

 {
         id: 1
         name: "test"
         type: "testType"
         locationType: "international"
         locationSpecific: "true"
         primary: true
         published: true
         sort: 1
         links: {
                 topics: "/topics?sourceId=1"
         }
    }

然后我的主题调用会返回这些对象

{
   id: 4
   sourceId: 1
   name: Topic 4
   type: "regTopic"
   sort: 1
}

我错过了什么吗?不能对'links'对象使用多态关系吗?

根据我对多态关系的理解,当我调用 /topics?sourceId=1 时,它本质上应该是在一次调用中加载 2 个不同的主题,这样我就可以在同一页面上显示 regTopic 和 summaryTopic 但分开显示列表并将它们作为单独的对象保存?

这是一个更新的 jsbin,似乎可以正常工作了。 http://emberjs.jsbin.com/medojitibo/1/edit?html,js,console,output

我看到的问题是,在我的控制器中,主题都是列表中的 App.Topic。没有 App.RegTopic 或 App.SummaryTopic

【问题讨论】:

标签: ember.js ember-data


【解决方案1】:

links 元素看起来像JSON-API,其中有一个addon。我不得不对我的fork 中的多态性进行修改。修改后端以支持 Ember Data 指定的 API 可能更容易。

【讨论】:

  • 链接元素与 RestAdapter 一起工作。它确实会调用去获取主题,但在那之后它永远不会将主题列表转换为特定主题(RegTopic 和 SummaryTopic)。另外,如果我没记错的话,您是否只修复了 belongsTo 而不是 hasMany 的链接多态关系?
【解决方案2】:

我不建议使用 Ember 数据多态性,除非您真的知道自己在做什么并且确信它可以满足您的需求。目前,它是为相当有限的用例而设计的。如果您有兴趣,可以跟踪有关该主题的许多讨论和建议。

您显然相信,或者 API 相信,source 对象的 JSON 中 links 属性的格式是一个包含单个 (?) topics 属性的对象,该属性为 API 端点提供检索一个多态的话题。这根本不是它的工作原理。

返回的 JSON 中links 属性的正确语法是{id, type} tuplets 的数组:

{
    id: 1
    name: "test"
    type: "testType"
    ...
    links: [
        { id: 'topic1', type: 'regTopic'},
        { id: 'topic2', type: 'summaryTopic' }
    ]
}

关联的数据格式,如上所示,是一个 id/type 对象的数组,而不仅仅是一个 id 的数组。这是 Ember Data 多态性工作所必需的。如果你不能让你的后端准确地产生这种格式,你最终会修补和破解适配器和序列化器中的许多方法,最终构建你自己的多态性版本,可能不会您希望开始的努力。

如果没有这种特殊形式的 JSON 用于关联属性,Ember Data 不知道要寻找什么类型的对象。有了它,Ember Data 将为这个 topics 数组中的每个条目创建正确的实例类型 topic,并基本上调用 find('reg-topic', 'topic1')find('summary-topic', 'topic2') 来获取它的数据。这意味着您还需要为每个主题子类型提供一个单独的 API 端点。 (如果主题是嵌入的,情况会有所不同,我不会在这里讨论替代方案。)

到目前为止,也许还不错。但是,一旦您开始做更复杂的事情,这种情况就会开始迅速崩溃。假设您想获取/检索具有特定 ID 的主题。有人可能会认为,既然“主题是多态的”,你就可以做this.store.get('topic', id)。但你不能。商店将RegTopics 和SummaryTopics 分别保存在不同的地方,并且不将它们与Topic 连接起来。如果您要求“主题”,它不知道在不同的(子)模型下查找已在商店中的实例。因此,您必须提前知道类型是什么,并要求商店提供该特定类型的记录,这有点违背了多态性的全部目的。如果您只是调用topics 端点,Ember Data 将为Topic 创建一个新模型实例——它不知道它应该检查返回的 JSON 的 type 字段来控制要转换它的子类型进入。

关键是这里的主题不是多态的。在 Ember Data 中,多态性不在 model 级别;它在关联级别。换句话说,这里的多态不是topic 模型本身;它是 source 模型的 links 属性中的关联。换句话说,Ember Data 不知道模型本身是多态的。它只知道特定关联(hasManybelongsTo)可以保存多态值。有关使 Ember Data 真正支持多态模型可能需要什么的一些见解,尽管上下文略有不同,请查看https://github.com/Bestra/ember-data-sti-guide

要在您的评论中回答您的问题,不,Ember Data 多态性不是做您想做的事的最佳方式。不要冒险进入这些未知的水域。我会采用“穷人的多态性”策略,您的Topic 模型有一个类型字段,并且可能或可能有一些不同的属性,具体取决于类型。然后,您可以根据自己的喜好对类型进行排序、分组和过滤。

【讨论】:

  • 您好 torazaburo,感谢您的回复!这整件事的发生是因为我想要一个有源列表的应用程序,这些源可以有三种不同类型的主题(有些只有两个,有些有全部三个)。根据来源,当您单击链接转到该来源主题时,我想在按主题类型分隔的列表中显示该来源的所有主题。因此,假设 Source 1 只有两种主题类型,Reg 和 Summary 主题。但来源 1 有 3 个 Reg 和 4 个摘要主题。最好的方法是什么? ember 多态性是解决这个问题的方法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-04
  • 1970-01-01
  • 2015-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多