我只是偶然发现了Ember Data Polymorphic Relationships。我认为它们对我正在做的事情很有用。这是我的主要模特。该模型定义了与异步和多态的主题有很多关系。
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
}
我错过了什么吗?你能不能在'链接'中使用多态关系?对象
根据我对多态关系的理解,当我调用/ topics?sourceId = 1时,它应该基本上在一个调用中加载2个不同的主题,这样我就可以在同一页面上显示regTopic和summaryTopic但是分开列出并将它们保存为单独的对象?
这是一个更新的jsbin,似乎接近工作。 http://emberjs.jsbin.com/medojitibo/1/edit?html,js,console,output
问题我看到它在我的控制器中,主题都是列表中的App.Topic。没有App.RegTopic或App.SummaryTopic
答案 0 :(得分:0)
答案 1 :(得分:0)
我不建议使用Ember Data多态性,除非你真的知道自己在做什么,并且确信自己能够满足你的需求。目前,它专为相当有限的用例而设计。如果您有兴趣,可以跟踪有关该主题的一些讨论和建议。
您显然相信,或者API认为,links
对象的JSON中source
属性的格式是包含单个(?)topics
属性的对象,给出用于检索多态主题的API端点。这根本不是它的工作方式。
返回的JSON中links
属性的正确语法是{id, type}
个连音符数组:
{
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将为此topic
数组中的每个条目创建topics
的正确实例类型,并基本上调用find('reg-topic', 'topic1')
和find('summary-topic', 'topic2')
来获取其数据。这意味着您还需要为每个主题子类型使用单独的API端点。 (如果主题是嵌入的,那么事情会有所不同,我不会在这里找到另一种选择。)
到目前为止,这很好,也许。但是一旦你开始做更复杂的事情,这就会开始迅速崩溃。假设您想要获取/检索具有特定ID的主题。有人可能认为,因为"主题是多态的",你可以做this.store.get('topic', id)
。但你不能。商店将RegTopic
和SummaryTopic
分隔在不同的位置,并且不会将其与Topic
相关联。如果您要求提供“主题”,则不知道在商店中已有的实例中查看不同(子)模型。因此,您必须事先知道类型是什么,并要求商店记录该特定类型,这种类型会破坏多态性的整个目的。如果您只是调用topics
端点,Ember Data将为Topic
创建一个新的模型实例 - 它不知道它应该检查返回的JSON的type
字段管理将其转换为什么子类型。
关键是这里的主题是不多态。在Ember Data中,多态性不在模型级别;它处于关联级别。换句话说,这里的多态是什么,不是topic
模型本身;它是links
模型上source
属性中的关联。换句话说,Ember Data不知道模型本身是多态的;它只知道特定的关联(hasMany
或belongsTo
)可以保存多态值。有关使Ember Data真正支持多态模型可能需要的一些见解,尽管情况略有不同,请查看https://github.com/Bestra/ember-data-sti-guide。
要在评论中回答您的问题,不,Ember Data多态性不是您想要的最佳方式。不要冒险进入这些未知的水域。我采用了“穷人的多态性"”的策略,其中Topic
模型具有类型字段,并且可能或可能具有一些不同的属性,具体取决于类型。然后,您可以根据心脏的内容对类型进行排序,分组和过滤。