私がember-dataで行うほとんどすべての場合に当てはまるように、単純なテストケースは非常に単純ですが、「本当の」ものは私の理解不足のためすぐにバラバラになります(そしてドキュメントだと思います)。最も単純なケースでは、新しいレコードを作成し、それをREST APIに保存しても問題ありません。よく使われているフルーツバスケットの例を使用して、新しい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);
さて、ここで問題はありません。概念的には理にかなっており、コードはクリーンで、物事は桃色に見えます! basket
モデルがあり、basket
モデルが多くのfruit
を保持できると仮定します。さらに、ユーザーは新しいfruit
を作成し、UIから1ステップでまだ作成されていない新しいbasket
に追加できます。
新しいモデルは次のとおりです。
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})
});
上記を考えると、ユーザーがストアまたはバックエンドREST APIに現在存在しない2つの新しいフルーツに入力し、それらを新しいバスケット(まだ存在しない)に追加してから、 「保存」を押します。
Emberデータを使用してこのレコードをどのように作成しますか?私はあなたがこのような何かをすることができることを望んでいました:
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);
残念ながら、これはうまくいかないようです。 POSTインスペクターのChromeリクエストデータを見ると、バスケットのfruits
プロパティは常に空です。基本的に、リクエストは次のようになります。
{
basket: {
fruits: []
}
}
正しいパターンを使用して「バスケット」レコードを作成していますか?バスケットを保存する前に、果物を1つずつ保存する必要がなくなることを望んでいます。1つで十分な場合に3つのPOSTリクエストを送信するのは無駄に思えます。さらに、ユーザーが10個の果物を作成したい場合はどうなりますか?それは11 POSTリクエストです。
上記を達成するための標準的なプラクティスはありますか?基本的に、hasMany関係のレコードも新規であるhasMany関係(バスケット)で新しいレコードをどのように作成しますか(フルーツ)。
ありがとうございました!
私が使用しているバージョンは次のとおりです。
-------------------------------
Ember : 1.3.2+pre.25108e91
Ember Data : 1.0.0-beta.7+canary.238bb5ce
Handlebars : 1.3.0
jQuery : 2.0.3
-------------------------------
私は自分でこれを理解しているだけですが、この方法でそれをやっただけで機能します...
まず、this.store.createRecord('basket', {})
を実行すると、fruits
プロパティに空の配列が必要です。だから、これを行う:
_var basket = this.store.createRecord('basket', {});
basket.get('fruits').addObject(this.store.createRecord('fruit', {
name: 'orange',
color: 'orange'
}));
basket.get('fruits').addObject(this.store.createRecord('fruit', {
name: 'banana',
color: 'yellow'
}));
_
ちなみに、空のfruits
配列は実際には_DS.PromiseArray
_(これはすぐに_DS.ManyArray
_?に解決される可能性があります)、_Ember.Array
_のより具体的なサブクラスです。差。
しかし、私が見つけたのは、fruits
プロパティがまったくシリアル化されないということです。ただし、JsonApiAdapterを使用しているため、could理由である。または、hasMany
子オブジェクトがまだ永続化されていない場合、これが予期される動作である可能性があります。とにかく、コントローラーのactions.saveメソッドで次のようなことをしました。
_basket.save().then(function(){
var promises = Ember.A();
basket.get('fruits').forEach(function(item){
promises.Push(item.save());
});
Ember.RSVP.Promise.all(promises).then(function(resolvedPromises){
alert('All saved!');
});
});
_
どういうわけか、魔法のように、すべてが完了すると、保存された「バスケット」、生成されたid
、および生成されたid
sで「果物」が保存されました。そして、すべての果物のbelongsTo
プロパティはバスケットを指しており、バスケットのhasMany
にはすべての果物が含まれていました…私がバスケットをsave()
d私のバックエンドからの応答はfruits
プロパティに対して空の配列を返しました。これは物事を混乱させると確信していましたが、どういうわけかそうではありませんでした。
もちろん、これらは私の実際のモデルではありませんでしたが、類似点は非常に近かったです。 Ember Data 1.0.0-beta5およびEmber 1.3.1を使用しています。ストックRESTアダプターを使用していませんが、JsonApiAdapterはかなり薄いシェルです。このアプローチを試して、動作するかどうかを確認してください。
同様の質問 を開きました。これは、上記のコードを使用して既存のレコードも更新する(新しいレコードを作成するのではなく)ことで発生した問題に対処します。このソリューションは、より一般的かつ詳細ですが、より複雑です。
また、(この例では)basket
が作成されたときに、fruits
プロパティ(_DS.PromiseArray
_)がまだ完全に準備されていない可能性があります。そのため、代わりに次のようにする必要があります。
_var basket = this.store.createRecord('basket', {});
basket.get('fruits').then(function(){
// Now the fruits array is available
basket.get('fruits').addObject(this.store.createRecord('fruit', { /* ... */ }));
});
_
他の誰かがこれに遅れている場合、現在のドキュメントでは、次のようにcreateRecord()
を単純に呼び出すことができると指摘しています。
post.get('comments').createRecord({})
post
が空のオブジェクトであっても機能します。