Ember.js & Ember Data: Comment créer un enregistrement avec hasMany relation lorsque le parent et l'enfant n'existent pas encore
Comme cela semble être le cas avec la plupart tout ce que je fais avec ember-data le simple cas de test est très simple, mais rien de "réel" tombe rapidement en raison de mon manque de compréhension (et je pense que la documentation). Dans le cas le plus simple je n'ai pas de problème de création d'un nouvel enregistrement et de l'enregistrer sur mon API REST. Je vais utiliser de la persistance de fruit le panier de l'exemple et commencer avec juste de l'enregistrement d'un nouveau morceau de fruit
.
//Here is our fruit model
module.exports = App.Fruit= DS.Model.extend({
name: attr('string'),
color: attr('string')
});
//This is easy to create and save
var fruit = this.store.createRecord('fruit', {
name: 'apple',
color: 'red'
});
fruit.save().then(successCallback, errorCallback);
D'accord, je n'ai pas de problème ici. Sur le plan conceptuel du sens, le code est propre, et les choses semblent peachy! Maintenant, supposons que nous avons un basket
modèle et que basket
modèle peut contenir beaucoup de fruit
. En outre, l'utilisateur peut créer de nouveaux fruit
et l'ajouter à un nouveau basket
qui n'a pas encore été créé en une seule étape, à partir de l'INTERFACE utilisateur.
Voici donc les nouveaux modèles:
module.exports = App.Fruit= DS.Model.extend({
name: attr('string'),
color: attr('string')
basket: DS.belongsTo('basket')
});
module.exports = App.Basket = DS.Model.extend({
fruits: DS.hasMany('fruit', {async:true})
});
Donné ci-dessus, permet de dire que les entrées d'utilisateur dans deux nouveaux fruits qui n'existent pas dans le magasin ou dans le backend API REST, ajoute à son nouveau panier (qui d'ailleurs n'existe pas encore) et frappe, puis "enregistrer".
Comment voulez-vous créer cet enregistrement à l'aide de Braise de Données? J'espérais que vous pourriez faire quelque chose comme ceci:
var newFruits = Ember.A();
newFruits.pushObject(this.store.createRecord('fruit', {
name: 'orange',
color: 'orange'
}));
newFruits.pushObject(this.store.createRecord('fruit', {
name: 'banana',
color: 'yellow'
}));
var basket = this.store.createRecord('basket', {
fruits: newFruits
});
basket.save().then(successCallback, errorCallback);
Malheureusement, cela ne semble pas fonctionner. Quand je regarde le POST de demande de données dans google Chrome, inspecteur de l' fruits
propriété du panier est vide. Fondamentalement, la demande finit par regarder ce:
{
basket: {
fruits: []
}
}
Suis-je utiliser le bon modèle pour créer le 'panier' enregistrement? J'espère que je n'ai pas de finir l'enregistrement de chaque morceau de fruit avant première économie de la nacelle, comme il semble un gaspillage d'envoyer 3 requêtes POST lorsque 1 suffirait. En outre, ce qui se passe lorsque l'utilisateur veut créer des 10 morceaux de fruits? Que serait 11 Requêtes POST.
Est-il une pratique standard pour l'accomplissement de ce qui précède? Essentiellement, comment voulez-vous créer un nouveau dossier avec un hasMany relation (panier) où les enregistrements dans la hasMany relation sont aussi de nouvelles (le fruit).
Merci!
Voici les versions que je suis en utilisant:
-------------------------------
Ember : 1.3.2+pre.25108e91
Ember Data : 1.0.0-beta.7+canary.238bb5ce
Handlebars : 1.3.0
jQuery : 2.0.3
-------------------------------
Vous devez vous connecter pour publier un commentaire.
Je suis juste en essayant de sortir moi-même, mais je l'ai fait de cette façon et ça fonctionne...
Pour commencer, lorsque vous
this.store.createRecord('basket', {})
il devrait venir avec un tableau vide pour l'fruits
de la propriété. Donc, faites ceci:D'ailleurs, le vide
fruits
tableau est en fait unDS.PromiseArray
(qui peut instantanément résoudre à unDS.ManyArray
?), un plus sous-classe spécifique deEmber.Array
, ce qui pourrait faire une différence.Cependant, ce que j'ai trouvé est que les
fruits
propriété de ne pas être sérialisé à tous, je suis en utilisant le JsonApiAdapter bien que, de sorte que pourrait être la raison. Ou peut être que c'est le comportement attendu lors de lahasMany
les objets enfants n'ont pas encore été persisté. De toute façon, j'ai juste fait quelque chose comme ça dans mon contrôleur.méthode d'enregistrement:En quelque sorte, comme par magie, quand tout ce qui a été fait, j'ai fini avec un sauvés "panier", avec un générés
id
, et enregistré les "fruits" avec générésid
s. Et, tous les fruits'belongsTo
propriétés de relever dos au panier et le panier dans lahasMany
contenait tous les fruits...malgré le fait que, quand jesave()
d le panier, la réponse de mon backend retourné un tableau vide pour monfruits
de la propriété, dont j'étais sûr serait gâcher les choses, mais en quelque sorte n'ont pas.Bien sûr, ce n'étaient pas mes modèles réels, mais le parallèle est très étroite. Je suis sur la Braise de Données de la version 1.0.0-beta5 et de Braise 1.3.1. Je ne suis pas en utilisant le stock RESTE de l'adaptateur, mais la JsonApiAdapter est une jolie coquille mince sur elle--donc, essayez cette approche et voir si cela fonctionne!
Modifier
J'ai ouvert un question similaire ici qui répond à un problème que j'ai rencontré en utilisant le code ci-dessus, également, de mettre à jour des enregistrements existants (par opposition à en créer de nouveaux). Cette solution est plus général et détaillé, mais plus complexe.
Aussi, potentiellement, un autre chat que j'ai rencontré est que quand (dans cet exemple) le
basket
est créé, lefruits
de propriété (qui est unDS.PromiseArray
) ne peut pas être totalement prêt. Vous devrez peut-être faire comme ceci à la place:fruits
array (bien, ils n'en ont pas, alors comment pourrait-il), donc je ne suis pas surpris qu'il ne poste pas les objets.Au cas où quelqu'un d'autre est d'arriver à cette fin, la documentation courante de points que vous pouvez simplement appeler
createRecord()
comme ceci:post.get('comments').createRecord({})
qui fonctionne même si
post
est un objet vide.store.createRecord
mais vous pouvez l'appeler sur une relation de tableau, telles quecomments
énumérés ci-dessus. Persister à vous fairenewComment = post.get('comments').createRecord({})
et puisnewComment.save()
comme d'habitude.