我很难理解模型关系在ember-data中的工作原理。我理解一对多或一对一或多对多的概念,但我不明白如何正确使用它。
我的API正在向我发送此数据:
{
gameweek: [
{
commonID: '23',
content: 'blablabla',
game: [
{
commonID: '23',
gameID: 4,
title: 'first game'
},
{
commonID: '23',
gameID: 8,
title: 'second game'
}
]
},
{
commonID: '24',
content: 'blebleble'
game: [
{
commonID: '24',
gameID: 12,
title: 'another game'
}
]
}
]
}
如您所见,我收到一个包含一些数据和另一个数组的数组。
如果我只有一个型号,我真的不知道如何创建模型?或像这样多个? (纠正我,如果错了):
//gameweek.js
import DS from "ember-data";
export default DS.Model.extend({
commonID: DS.attr('string'),
title: DS.attr('string'),
games: DS.hasMany('game')
});
//game.js
import DS from "ember-data";
export default DS.Model.extend({
commonID: DS.attr('string'),
title: DS.attr('string'),
gameweek: DS.belongsTo('gameweek')
});
我希望能够将我的数组保存在商店中并保持它们之间的关系。
如果我做this.store.find('gameweek', {commonID: '23'} );
我想获得与游戏周相关的所有游戏。 (如果相关,则commonID将是相同的。)
我是否必须创建自定义序列化程序?
这么多问题,谢谢你的帮助!
=============================
更新:
我试图像这样扩展DS.RESTSerializer
:
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
extractArray: function( store, type, record ) {
var gameweek = record.predictions;
gameweek.forEach(function( entry ) {
var data = entry.games.map(function(game) {
return game.gameID;
});
entry.games = data;
});
record = { prediction: gameweek };
return this._super( store, type, record );
}
});
这主要是用gameID数组替换我的游戏数组,新数组如下所示:
{
gameweek: [
{
commonID: '23',
content: 'blablabla',
game: ["4", "8"]
},
{
commonID: '24',
content: 'blebleble'
game: ["12"]
}
]
}
但是我收到了这个错误:
Error: Assertion Failed: Unable to find transform for 'integer'
我不知道该怎么做。
===================================
UPDATE2:
我也试过了:
//serializers/gameweek.js
import DS from "ember-data";
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
primaryKey: 'gameWeekID',
attrs: {
game: { embedded: 'load' }
},
extractArray: function( store, type, record ) {
// The array of object isn't at the root structure of the record
var record = record.predictions;
record = { prediction: record };
return this._super( store, type, record );
}
});
//serializers/game.js
import DS from "ember-data";
export default DS.RESTSerializer.extend({
primaryKey: 'gameID'
});
我收到了这个错误:
Error: Assertion Failed: Ember Data expected a number or string to represent the record(s) in the "games" relationship instead it found an object. If this is a polymorphic relationship please specify a "type" key. If this is an embedded relationship please include the "DS.EmbeddedRecordsMixin" and specify the "games" property in your serializer's attrs object.
答案 0 :(得分:0)
在ember中,你不要将数组保存为模型,将对象保存为模型。 Ember数据需要以某种方式返回数据,因此您需要执行此服务器端或使用序列化程序执行此操作 如果你的模型设置清楚,你可以保存关系没问题 在以下来自余烬网站的代码中,您的模型是一个帖子。因此,当您查询帖子时,这应该返回。帖子与评论有关系。帖子有很多评论和评论属于帖子。在post模型中,每个注释的id都与该帖子相关,然后注释作为单独的数组包含在内。 http://guides.emberjs.com/v1.12.0/models/the-rest-adapter/#toc_sideloaded-relationships
{
"post": {
"id": 1,
"title": "Node is not omakase",
"comments": [1, 2, 3]
},
"comments": [{
"id": 1,
"body": "But is it _lightweight_ omakase?"
},
{
"id": 2,
"body": "I for one welcome our new omakase overlords"
},
{
"id": 3,
"body": "Put me on the fast track to a delicious dinner"
}]
}
上述结构的相关模型文件是
应用/模型/ post.js 强>
export default DS.Model.extend({
title: DS.attr('string'),
comments: DS.hasMany('comment')
});
应用/模型/ comment.js 强>
export default DS.Model.extend({
body: DS.attr('string'),
post: DS.belongsTo('post')
});
我不知道它只是我的脑袋或它的结束,但上面的命名和结构布局非常令人困惑。您是否可以包含更多细节或使细节不那么通用,它可能有助于尝试计算数据。
答案 1 :(得分:0)
您应该为gameweek
和game
设置单独的模型。 Ember Data使用更精细的模型更好地工作,而不是尝试处理作为原始对象的模型字段。这将使得将来使用其他功能(例如计算属性和验证器)扩展游戏模型变得容易。所以你建议的模型结构很好。
但是,要使用当前的JSON结构,您必须声明game
嵌入。要做到这一点
// serializers/gameweek.js
import ApplicationSerializer from './application';
import DS from 'ember-data';
export default ApplicationSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
games: { embedded: 'load' }
}
});
我们从ApplicationSerializer
作为最佳实践继承,如果它指定了这些特定于模型的序列化程序继承的东西。
此外,Ember Data将坚持每个游戏的唯一ID,因此它有一种方法可以在商店中识别它。如果gameId
是唯一的,您可以按原样使用,但您必须通过说
// serializers/game.js
import ApplicationSerializer from './application';
import DS from 'ember-data';
export default ApplicationSerializer.extend({
primaryKey: 'gameId'
});
执行此操作后,您将不再将ID称为gameId
;您将其称为id
,并且您不需要也不应该将其声明为模型的一部分。