admin管理员组文章数量:1025227
I have a problem similar to this stack overflow question, except the answer doesn't seem to be working. I have a form in which the user creates a container module with a variable number of submodels. When the form is submitted, I have to save the container, the submodels, and make sure that the the hasMany relationship persists. My code (using Ember-Cli):
container:
var Container= DS.Model.extend({
name: DS.attr('string'),
submodels: DS.hasMany('submodel'),
lastModified: DS.attr('date')
});
export default Container;
submodel:
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(...);
}
}
});
The Ember Data itself works fine, transition to a view of the created container, with submodels listed. Refresh the page, and the submodels disappear from the container view.
I've tried a few variations, for example using pushObject rather than the addObject from the stack overflow answer. I've also tried using the Ember.RSVP callback to run container.save() a second time after the submodels have been saved.
After some further testing, I've found that the submodels are not persisting at all.
Is there a sane way to save 1) the container 2) the submodels 3) the hasMany/belongsTo relationships to each other?
Or does this some how need to be broken down into discrete steps where I save the container, save the submodels, the push the submodels to the container to get the hasMany relationship and resave the container, and lastly make the submodels belongTo the container and save the submodels again?
I have a problem similar to this stack overflow question, except the answer doesn't seem to be working. I have a form in which the user creates a container module with a variable number of submodels. When the form is submitted, I have to save the container, the submodels, and make sure that the the hasMany relationship persists. My code (using Ember-Cli):
container:
var Container= DS.Model.extend({
name: DS.attr('string'),
submodels: DS.hasMany('submodel'),
lastModified: DS.attr('date')
});
export default Container;
submodel:
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(...);
}
}
});
The Ember Data itself works fine, transition to a view of the created container, with submodels listed. Refresh the page, and the submodels disappear from the container view.
I've tried a few variations, for example using pushObject rather than the addObject from the stack overflow answer. I've also tried using the Ember.RSVP callback to run container.save() a second time after the submodels have been saved.
After some further testing, I've found that the submodels are not persisting at all.
Is there a sane way to save 1) the container 2) the submodels 3) the hasMany/belongsTo relationships to each other?
Or does this some how need to be broken down into discrete steps where I save the container, save the submodels, the push the submodels to the container to get the hasMany relationship and resave the container, and lastly make the submodels belongTo the container and save the submodels again?
Share Improve this question edited May 23, 2017 at 10:34 CommunityBot 11 silver badge asked Jun 13, 2014 at 19:25 ansorensenansorensen 1,3162 gold badges15 silver badges29 bronze badges 2- Will you please label what the exported routes/controllers are? It's difficult to guess how things are related when you just get an export. Thanks! – Kingpin2k Commented Jun 14, 2014 at 5:04
- Will you also please include the model definitions? – Kingpin2k Commented Jun 14, 2014 at 5:15
2 Answers
Reset to default 6 +50The Problem
By default, DS.hasMany
on a one to many association won't include ids
field when serializing. You can use DS.EmbeddedRecordsMixin
to change this behavior.
More Info
Please read Embedded Records Mixin section on A Thorough Guide to Ember Data for more. (disclaimer, I'm its author.)
Here is an excerpt
DS.EmbeddedRecordsMixin
is an extension for DS.ActiveModelSerializer
which allows configuring of how associations get serialized or deserialized. Although not yet plete (especially with regard to polymorphic associations), it is intriguing nonetheless.
You can choose:
- Not to serialize or deserialize associations.
- To serialize or deserialize associations with id or ids.
- To serialize or deserialize associations with embedded models.
Code Sample:
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})
});
You have the problem that I've experienced earlier, you have easier example than my cause you need only one relation :hasMany and :belongsTo
Try to use this approach:
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('[email protected]'),
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');
}
}
});
Good luck ;)
I have a problem similar to this stack overflow question, except the answer doesn't seem to be working. I have a form in which the user creates a container module with a variable number of submodels. When the form is submitted, I have to save the container, the submodels, and make sure that the the hasMany relationship persists. My code (using Ember-Cli):
container:
var Container= DS.Model.extend({
name: DS.attr('string'),
submodels: DS.hasMany('submodel'),
lastModified: DS.attr('date')
});
export default Container;
submodel:
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(...);
}
}
});
The Ember Data itself works fine, transition to a view of the created container, with submodels listed. Refresh the page, and the submodels disappear from the container view.
I've tried a few variations, for example using pushObject rather than the addObject from the stack overflow answer. I've also tried using the Ember.RSVP callback to run container.save() a second time after the submodels have been saved.
After some further testing, I've found that the submodels are not persisting at all.
Is there a sane way to save 1) the container 2) the submodels 3) the hasMany/belongsTo relationships to each other?
Or does this some how need to be broken down into discrete steps where I save the container, save the submodels, the push the submodels to the container to get the hasMany relationship and resave the container, and lastly make the submodels belongTo the container and save the submodels again?
I have a problem similar to this stack overflow question, except the answer doesn't seem to be working. I have a form in which the user creates a container module with a variable number of submodels. When the form is submitted, I have to save the container, the submodels, and make sure that the the hasMany relationship persists. My code (using Ember-Cli):
container:
var Container= DS.Model.extend({
name: DS.attr('string'),
submodels: DS.hasMany('submodel'),
lastModified: DS.attr('date')
});
export default Container;
submodel:
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(...);
}
}
});
The Ember Data itself works fine, transition to a view of the created container, with submodels listed. Refresh the page, and the submodels disappear from the container view.
I've tried a few variations, for example using pushObject rather than the addObject from the stack overflow answer. I've also tried using the Ember.RSVP callback to run container.save() a second time after the submodels have been saved.
After some further testing, I've found that the submodels are not persisting at all.
Is there a sane way to save 1) the container 2) the submodels 3) the hasMany/belongsTo relationships to each other?
Or does this some how need to be broken down into discrete steps where I save the container, save the submodels, the push the submodels to the container to get the hasMany relationship and resave the container, and lastly make the submodels belongTo the container and save the submodels again?
Share Improve this question edited May 23, 2017 at 10:34 CommunityBot 11 silver badge asked Jun 13, 2014 at 19:25 ansorensenansorensen 1,3162 gold badges15 silver badges29 bronze badges 2- Will you please label what the exported routes/controllers are? It's difficult to guess how things are related when you just get an export. Thanks! – Kingpin2k Commented Jun 14, 2014 at 5:04
- Will you also please include the model definitions? – Kingpin2k Commented Jun 14, 2014 at 5:15
2 Answers
Reset to default 6 +50The Problem
By default, DS.hasMany
on a one to many association won't include ids
field when serializing. You can use DS.EmbeddedRecordsMixin
to change this behavior.
More Info
Please read Embedded Records Mixin section on A Thorough Guide to Ember Data for more. (disclaimer, I'm its author.)
Here is an excerpt
DS.EmbeddedRecordsMixin
is an extension for DS.ActiveModelSerializer
which allows configuring of how associations get serialized or deserialized. Although not yet plete (especially with regard to polymorphic associations), it is intriguing nonetheless.
You can choose:
- Not to serialize or deserialize associations.
- To serialize or deserialize associations with id or ids.
- To serialize or deserialize associations with embedded models.
Code Sample:
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})
});
You have the problem that I've experienced earlier, you have easier example than my cause you need only one relation :hasMany and :belongsTo
Try to use this approach:
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('[email protected]'),
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');
}
}
});
Good luck ;)
本文标签: javascriptEmber Data model and hasMany submodels not persistingStack Overflow
版权声明:本文标题:javascript - Ember Data: model and hasMany submodels not persisting - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745613940a2159171.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论