我现在正在学习Ember Data,而且我遇到了一个问题,如果不编写丑陋的代码我就无法解决(这是我自己的项目所以我有时间尽我所能)。问题是: 我有3个模型:帖子,用户和评论。代码将更好地描述我的意思;)
/* Post Model */
Blog.Post = DS.Model.extend({
title: DS.attr('string'),
text: DS.attr('string'),
postedAt: DS.attr('string', { defaultValue: new Date() }),
comments: DS.hasMany("comment", { async: true })
});
/* ==Post Model== */
/* User Model */
Blog.User = DS.Model.extend({
name: DS.attr('string'),
avatar: DS.attr('string'),
comments: DS.hasMany("comment", { async: true })
});
/* ==User Model== */
/* Comment Model */
Blog.Comment = DS.Model.extend({
title: DS.attr("string"),
text: DS.attr("string"),
user: DS.belongsTo("user", { async: true }),
post: DS.belongsTo("post", { async: true }),
postedAt: DS.attr("date", { defaultValue: new Date() })
});
/* ==Comment Model== */
/* Post Controller (bad variant and it doesn't work - too many redirects error) */
leaveComment: function () {
var controller = this,
user = controller.get('user'),
post = controller.get('model');
var comment = this.get('store').createRecord('comment', {
title: controller.get('commentTitle'),
text: controller.get('commentText'),
user: user,
post: post
});
comment.save().then(function (res) {
controller.setProperties({
commentTitle: "",
commentText : ""
});
user.get("comments").then(function (comments) {
comments.pushObject(comment);
user.save().then(function (ures) {
console.log(ures);
post.get("comments").then(function (comments) {
comments.pushObject(comment);
post.save().then(function (pres) {
console.log(pres)
}, function (err) {
console.log(err);
});
});
}, function (err) {
console.log(err);
})
});
}, function (err) {
console.log(err);
});
/* ==Post Controller== */
/* Post Route */
Blog.PostRoute = Ember.Route.extend({
setupController: function (controller, model) {
this._super(controller, model);
controller.setProperties({
user: this.modelFor('application')
});
},
model: function(params) {
return this.store.find('post', params["post_id"]);
}
});
/* ==Post Route== */
/* 2nd variant */
/* Post Controller */
leaveComment: function () {
var controller = this,
user = controller.get('user'),
post = controller.get('model');
var comment = this.get('store').createRecord('comment', {
title: controller.get('commentTitle'),
text: controller.get('commentText'),
user: user,
post: post
});
comment.save().then(function (res) {}, function(err) { console.log(err) });
/* ==Post Controller== */
/* Application.js */
Blog.CommentSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
primaryKey: function() {
return '_id';
}.property(),
attrs: {
user: { embedded: 'always' },//{serialize: 'id', deserialize: 'id'},
post: { embedded: 'always' }//{serialize: 'id', deserialize: 'id'}
}
});
/* ==Application.js== */
使用第二个变体,当我执行保存时,我在预览数据中有用户/帖子ID而不是对象 - 可能我不明白如何使用它。如果你有类似的经历,请帮助我。
更新
当我使用第一个变体发出请求时 - 错误:网络错误 - 重定向太多
当我使用第二个变体发出请求时:
1)似乎DS.ActiveModelSerializer根本不起作用 2)在请求中有user_id和post_id,而不是嵌入对象,实际上对我来说并不意味着 - 发送嵌入对象或id,只关心我关心的是更新相关模型。 考虑屏幕截图以便更好地理解
当然,在保存之后,它不包括在post.get(“comments”)和user.get(“comments”)属性中保存注释。
P.S。我也搜索谷歌很长一段时间没有得到我的问题的回复,所以请不要回答,如果你对你的答案没有信心 - 感谢理解
=============================================== ===============================================
经过几个小时的痛苦,我想出了这个:
//Controller
comments: function () {
return this.get('model.comments')
}.property('model.@each.comments'),
post: function () {
return this.get('model');
}.property('post'),
user: function () {
return this.get('user');
}.property('user'),
actions: {
leaveComment: function () {
var controller = this,
user = controller.get('user'),
post = controller.get('post');
var comment = this.get('store').createRecord('comment', {
text: controller.get('commentText'),
user: user,
post: post,
postedAt: new Date()
});
comment.save().then(function (comment_res) {
controller.get("comments").pushObject(comment_res);
post.save().then(function (post_res) {
controller.set("commentText", "");
}, function (err) {
console.log(err);
});
}, function (err) {
console.log(err);
});
}
}
Blog.CommentSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
primaryKey: function () {
return '_id';
}.property()//,
//attrs: {//{ embedded: 'always' },
// user: { embedded: 'always' }, //{serialize: 'id', deserialize: 'id'},
// post: { embedded: 'always' } //{serialize: 'id', deserialize: 'id'}
//} // <-this doesn't work :\
});
Blog.PostSerializer = DS.ActiveModelSerializer.extend({
primaryKey: function () {
return '_id';
}.property(),
serializeHasMany: function(record, json, relationship) {
var key = relationship.key;
var json_key = key.singularize().decamelize() + '_ids';
var relationshipType = DS.RelationshipChange.determineRelationshipType(
record.constructor, relationship);
if (relationshipType === 'manyToNone'
|| relationshipType === 'manyToMany'
|| relationshipType === 'manyToOne') {
json[json_key] = Ember.get(record, key).mapBy('id');
}
}// <- And this really works!
正如您所看到我只更新 1 相关型号 - 发布,我无法更新用户模型,因为:太多的重定向:错误(我在Post和Comment之间有双向链接,与User的单向链接(Comment belongsTo User),我不能在comments属性中带有User的注释)。到目前为止,这是不可能的。另外,我对 DS.EmbeddedRecordMixin 感到非常难过:(在找到我的问题的答案之前,我不会关闭这个主题,但是 - 感谢您的帮助!
答案 0 :(得分:2)
@Craicerjack,
嗯,这可能有点令人困惑 - 我解释这样的事情:)
我会尝试简化:我们有3个模型:Post
,User
和Comment
。 Post
有Comment
个,User
有Comment
个,Comment
属于Post
,Comment
属于User
。这就是模型配置所描述的,很容易理解它,但很重要。
现在,很难(对我而言)部分:我们将发表评论!创建记录,comment.save()
向服务器生成ajax调用(post类型)。我们的评论对象包含commentText
,createdAt
和&#34;链接/参考/关系&#34;相对模型 - post_id
和user_id
-
comment.save().then(function(responseFromSavedComment) {
// we will insert next steps here...
});
这很好。现在我们需要更新我们的Post
模型和User
模型;我们刚刚添加了Comment
,还记得吗?好!首先,我们将更新Post
;我们需要提取post.get('comments')
,返回Promise
,然后推送并反对其响应,对吧?
post.get('comments').then(function(postComments) {
postComments.pushObject(responseFromSavedComment);
});
当我们发布评论本身时,我们只是将最近创建的评论推送到承诺解决范围内的帖子。明确?完善!
我们完成Post更新所需的最后一件事是通知服务器这个,我们只是做post.save()
! :)那就是全部!
但是,如果我们想以同样的方式更新用户模型,我们会遇到:TOO_MANY_REDIRECTS:
错误,那就是......我们无法在范围(时间)内执行此操作添加评论...
我找到了解决方案 - 不使用嵌入式记录:)服务器将获取密钥并执行所有操作。现在无法在客户端完全处理这个问题。
答案 1 :(得分:0)
/* Post Controller */
leaveComment: function () {
var user = this.get('user');
var post = this.get('post');
var comment = this.store.createRecord('comment', {
title: this.get('commentTitle'),
text: this.get('commentText'),
user: user,
post: post
});
this.get('model').pushObject(comment);
comment.save();
};
/* ==Post Controller== */