javascript 如何使嵌入的 hasMany 关系与 ember 数据一起工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14320925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make embedded hasMany relationships work with ember data
提问by Riad
I can't get embedded
hasMany
to work correctly with ember data.
我无法embedded
hasMany
使用 ember 数据正常工作。
I have something like this
我有这样的事情
App.Post = DS.Model.extend({
comments: DS.hasMany('App.Comment')
});
App.Comment = DS.Model.extend({
post: DS.hasMany('App.Post'),
name: attr('string')
});
And my API returns the following for GET /post
:
我的 API 返回以下内容GET /post
:
[
{
id: 1
comments: [{name: 'test'}, {name: 'test2'}]
},
...
]
I need to send this with POST /post
:
我需要发送这个POST /post
:
[
{
comments: [{name: 'test'}, {name: 'test2'}]
},
...
]
I want to work with Ember models and have them make the appropriate requests:
我想使用 Ember 模型并让它们提出适当的请求:
var post = App.store.createRecord(App.Post, hash_post_without_comments);
post.get('comments').createRecord(hash_comment);
App.store.commit(); // This should call the POST api
and
和
var posts = App.store.find(App.Post); // This should call the GET api
When I try something like post: DS.hasMany('App.Post', {embedded: true})
, the GET is working but the POST is trying to make a POST for the two records not only the parent one.
当我尝试类似的操作时post: DS.hasMany('App.Post', {embedded: true})
,GET 正在运行,但 POST 试图为两条记录进行 POST,而不仅仅是父记录。
EDIT : My Real use case
编辑:我的真实用例
1- I've just built ember data from master
1- 我刚刚从 master 构建了 ember 数据
2- My adapter: RESTAdapter
2- 我的适配器:RESTAdapter
3- The serializer: JSONSerializer
3- 序列化器:JSONSerializer
4- I added
4-我添加了
App.MyAdapter.map('App.Join', {
columns: { embedded: 'always' }
});
5- My Models are:
5- 我的模型是:
App.Join = DS.Model.extend({
rowCount: DS.attr('number'),
columns: DS.hasMany('App.JoinColumn'),
});
App.JoinColumn = DS.Model.extend({
join: DS.belongsTo('App.Join')
});
6- When:
6- 什么时候:
var a = App.Join.find(1);
a.get('columns').createRecord({});
App.store.commit();
a POST for joincolumn is sent and the parent is not dirty
发送了 joincolumn 的 POST 并且父级不脏
What am i missing?
我错过了什么?
采纳答案by bobey
I have the exact same problem.
我有完全一样的问题。
This bug has been reported on the ember data issue tracker. The following PR adds 2 failing tests showing the problem: https://github.com/emberjs/data/pull/578
此错误已在 ember 数据问题跟踪器上报告。以下 PR 添加了 2 个显示问题的失败测试:https: //github.com/emberjs/data/pull/578
It seems that there is no workaround right now.
目前似乎没有解决方法。
EDIT:
编辑:
sebastianseilundopened a PR 2 days ago which fixes your problem. Have a look at: https://github.com/emberjs/data/pull/629/files
sebastianseilund2 天前打开了一个 PR,它解决了您的问题。看看:https: //github.com/emberjs/data/pull/629/files
回答by Yehuda Katz
On master, the correct API is:
在 master 上,正确的 API 是:
App.Adapter.map('App.Post', {
comments: { embedded: 'always' }
});
The two possible values of embedded
are:
的两个可能值embedded
是:
load
: The child records are embedded when loading, but should be saved as standalone records. In order for this to work, the child records must have an ID.always
: The child records are embedded when loading, and are saved embedded in the same record. This, of course, affects the dirtiness of the records (if the child record changes, the adapter will mark the parent record as dirty).
load
: 加载时嵌入子记录,但应保存为独立记录。为了使其工作,子记录必须有一个 ID。always
: 子记录在加载时嵌入,并嵌入在同一记录中保存。这当然会影响记录的脏程度(如果子记录发生变化,适配器会将父记录标记为脏)。
If you don't have a custom adapter, you can call map
directly on DS.RESTAdapter
:
如果您没有自定义适配器,则可以map
直接调用DS.RESTAdapter
:
DS.RESTAdapter.map('App.Post', {
comments: { embedded: 'always' }
});
回答by steakchaser
Adding an update to this incase others come across this post and are having a hard time figuring out what works with the current version of ember-data.
添加一个更新,以防其他人看到这篇文章,并且很难弄清楚什么适用于当前版本的 ember-data。
As of Ember Data 1.0.0.beta.7, you need to override the appropriate methods on the serializer. Here's an example:
从 Ember Data 1.0.0.beta.7 开始,您需要覆盖序列化程序上的适当方法。下面是一个例子:
1) Reopen the serializer (credit to this post):
1)重新打开序列化程序(归功于这篇文章):
DS.RESTSerializer.reopen({
serializeHasMany: function(record, json, relationship) {
var hasManyRecords, key;
key = relationship.key;
hasManyRecords = Ember.get(record, key);
if (hasManyRecords && relationship.options.embedded === "always") {
json[key] = [];
hasManyRecords.forEach(function(item, index) {
// use includeId: true if you want the id of each model on the hasMany relationship
json[key].push(item.serialize({ includeId: true }));
});
} else {
this._super(record, json, relationship);
}
}
});
2) Add the embedded: 'always'
option to the relationship on the model:
2)embedded: 'always'
在模型上的关系中添加选项:
App.Post = DS.Model.extend({
comments: DS.hasMany('comment', {
embedded: 'always'
})
});
回答by Patrick Fisher
This is what worked for me (Ember 1.5.1+pre.5349ffcb, Ember Data 1.0.0-beta.7.f87cba88):
这对我有用(Ember 1.5.1+pre.5349ffcb,Ember Data 1.0.0-beta.7.f87cba88):
App.Post = DS.Model.extend({
comments: DS.hasMany('comment', { embedded: 'always' })
});
App.PostSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
comments: { embedded: 'always' }
}
});