我遇到类似this stack overflow question的问题,但答案似乎没有效果。我有一个表单,用户在其中创建一个包含可变数量子模型的容器模块。提交表单时,我必须保存容器,子模型,并确保hasMany关系仍然存在。我的代码(使用Ember-Cli):
容器:
var Container= DS.Model.extend({
name: DS.attr('string'),
submodels: DS.hasMany('submodel'),
lastModified: DS.attr('date')
});
export default Container;
子模型:
var Submodel= DS.Model.extend({
char: DS.belongsTo('container'),
name: DS.attr('string'),
desc: DS.attr('string'),
priority: DS.attr('number'),
effort: DS.attr('number'),
time: DS.attr('number')
});
export default Submodel;
ContainersNewRoute:
export default Ember.Route.extend({
model: function() {
return this.store.createRecord('container', {
...
});
}
});
ContainersNewController:
export default Ember.ObjectController.extend({
actions: {
addSubmodel: function() {
var submodels= this.get('model.submodels');
submodels.addObject(this.store.createRecord('submodel', {
...
}));
},
saveNewContainer: function () {
var container = this.get('model');
container.save().then(function(){
var promises = Ember.A();
container.get('submodels').forEach(function(item){
promises.push(item.save);
console.log(item);
});
Ember.RSVP.Promise.all(promises).then(function(resolvedPromises){
alert('all saved');
});
});
this.transitionToRoute(...);
}
}
});
Ember Data本身工作正常,过渡到创建容器的视图,列出了子模型。刷新页面,子模型从容器视图中消失。
我尝试了一些变体,例如使用pushObject而不是堆栈溢出答案中的addObject。我已经尝试使用Ember.RSVP回调在子模型保存后第二次运行container.save()。
经过一些进一步的测试后,我发现子模型根本不存在。
是否有一种理智的方法来保存1)容器2)子模型3)hasMany / belongsTo彼此之间的关系?
或者这有些需要分解成离散步骤,我保存容器,保存子模型,将子模型推送到容器以获得hasMany关系并重新保存容器,最后使子模型属于容器并再次保存子模型?
答案 0 :(得分:6)
默认情况下,序列化时,一对多关联中的DS.hasMany
不会包含ids
字段。您可以使用DS.EmbeddedRecordsMixin
更改此行为。
请阅读Embedded Records Mixin section on A Thorough Guide to Ember Data了解更多信息。 (免责声明,我是它的作者。)
DS.EmbeddedRecordsMixin
是DS.ActiveModelSerializer
的扩展,它允许配置关联如何序列化或反序列化。虽然尚未完成(特别是关于多态关联),但它仍然很有趣。
您可以选择:
代码示例:
App.CartSerializer = DS.ActiveModelSerializer
.extend(DS.EmbeddedRecordsMixin)
.extend{
attrs: {
items: {serialize: 'ids', deserialize: 'ids'}
}
});
App.Cart = DS.Model.extend({
items: DS.hasMany('item', {async: true})
});
App.Item = DS.Model.extend({
cart: DS.belongsTo('item', {async: true})
});
答案 1 :(得分:1)
你遇到了我之前遇到的问题,你有一个比我原因更简单的例子你只需要一个关系:hasMany和:belongsTo
尝试使用这种方法:
export default Ember.ObjectController.extend({
// here we can pre-load submodels container,
//even if it's empty because 'this.get('model.submodels')' returns promise
submodels: function () {
return this.get('model.submodels');
}.property('model.@each.submodels'),
actions: {
addSubmodel: function () {
//saving context of controller, saving container for
//better understanding (clear vision)
var controller = this,
container = controller.get('conrtainer');
//container instead of 'model' for better understanding :)
//1. Creating submodel
var submodel = this.get('store').createRecord('submodel', {
// ... //
container: container
});
//2. Saving submodel
submodel.save().then(function (submodel_res) {
//3. It isn't the end though :)
//Now we're getting our submodels from the container - here we will get
//the result instead of promise, remember we pre-loaded it :) -1 nesting lvl
controller.get("submodels").pushObject(submodel_res);
//4. Now we need to update our 'parent' model - Container
container.save().then(function (post_res) {
console.log(post_res); // 5. Doesn't matter we are happy
}, function (err) {
console.log(err);
});
}, function (err) {
console.log(err);
});
}
}
});
//In order to use this approach you need to override property
//in model serializer (just copy it and //paste :) )
YourApp.ContainerSerializer = DS.ActiveModelSerializer.extend({
// here coulbe be RESTSerializer as well ;)
primaryKey: function () {
return '_id';
}.property(),
// it's just helpful tip, if you use mongo like me ;)
//it doesn't relates to the main topic itself
// this little method will help you update 'parent' model ;)
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');
}
}
});
祝你好运;)