问题
Ember data expects my server to return the full object after each successful POST
. However, my API only returns a kind of meta-object that contains the id
. When Ember receives this object, the existing data in the record gets deleted except for the id
.
So for example, when I do this:
var asset = App.Asset.store.createRecord('asset',{name: 'foo.ai',
paths: ['/path/foo.ai', '/another/path/foo.ai'],
type: 'ai',
hash: '1234567890123456789012345678901234567890',
datecreated: 'Sun, 12 Jan 2014 06:01:48 GMT',
datemodified: 'Sun, 12 Jan 2014 06:01:48 GMT',
thumbnail: '/path/to/thumb.jpg'
});
asset.save();
... the server responds, like so:
{
status: "OK",
updated: "Mon, 13 Jan 2014 19:49:14 GMT",
id: "52d4433a8e3b08444740ea47",
}
When Ember receives this, it updates the id
of the record with what it received in the server response, but it also deletes all the other data because it wasn't in the response. If I examine my data in the Ember helper, it looks like this:
{
id: '52d4433a8e3b08444740ea47'
name: undefined,
paths: undefined,
type: undefined,
hash: undefined,
datecreated: undefined,
datemodified: undefined,
thumbnail: undefined
}
How can I override this behavior and get Ember to stop deleting my data?
I've looked at:
- Hooking into
createRecord
in theDS.RESTAdapter
, but it returns a promise, so I can't extract the newid
yet. - Hooking into
extractSave
in theDS.RESTSerializer
, but it expects thestore
,type
, andpayload
as inputs, not the individualrecord
! If the record were passed into here, I could update itsid
with what's in the payload and solve my problem.
Is there something that I'm missing?
回答1:
Looks like the existing data on the record is getting overwritten in the record's adapterDidCommit
method.
See https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/model/model.js#L656-L657
One solution could be to extend that method to preserve existing data from the record. I believe it might look something like this.
DS.Model.reopen({
adapterDidCommit: function() {
var oldData = this.toJSON();
this._super.apply(this, arguments); // calls the original adapterDidCommit method
var newData = this._data;
this._data = Ember.merge(oldData, newData);
}
});
This code is probably not ideal because it modifies the DS.Model
class but I didn't see a way to extend an adapter or serializer class to achieve a similar result.
回答2:
For what it's worth, I'm solving my problem at the moment with the following:
// Given a vanilla Javascript `data` object that contains your model data
var asset = App.Asset.store.createRecord('asset', data);
asset.save();
// The server response updated `asset` with an `id` but deleted everything
// else, so we copy the `id` to our `data` object and then update the store
data.id = asset.id;
App.Asset.store.update('asset', data);
This solution feels hacky and I'd much rather get it right the first time than do this little dance every time I need to save a record.
来源:https://stackoverflow.com/questions/21100712/how-do-i-save-data-to-my-ember-store-if-the-post-response-contains-only-an-id