Как сохранить запись Ember Data, не отправляя ее на сервер?
Таким образом, Ember Data Model имеет deleteRecord()
который выполняет destroyRecord()
без отправки его в бэкэнд.
Как мне это сделать save()
без отправки его в бэкэнд?
Причина, по которой мне это нужно, заключается в том, что я использую пользовательский сервис для пакетного сохранения нескольких записей разных типов (моделей) в одном запросе. Я успешно отправляю запросы, и записи сохраняются на сервере.
Но так как запрос не проходит через конвейер Ember Data, ответ от сервера будет отброшен, если я не обработаю его вручную.
В основном, у меня есть это в сервисе:
// Accepts an array of records of mixed types,
// both existing and new
batchSave (records) {
this
.customAjax(records) // The records are persisted
.then(payload => { // Response from the backend with updated records
store.pushPayload(payload); // Now all records have been updated with their current state
// Now all the records are in their current state.
// But they are still dirty!
// How do I mark them clean and saved
});
Я видел это, но, кажется, отбрасывает грязные атрибуты, в то время как я хочу, чтобы грязные атрибуты стали чистыми.
Я также пытался store.didSaveRecord()
но после этого записи все еще грязные.
3 ответа
Это расширение предложения @Tom Netzband с большим количеством сахара.
Во-первых, миксин для адаптеров:
// mixins/prevent-save-adapter.js
export default Ember.Mixin.create({
preventSave: false,
updateRecord(store, type, snapshot) {
if (!this.get('preventSave'))
return this._super(store, type, snapshot);
this.set('preventSave', false);
return true;
}
});
Тогда один для моделей:
// mixins/prevent-save-model.js
export default Ember.Mixin.create({
saveWithoutSave() {
var modelName = this.constructor.modelName;
var adapter = this.adapterFor(modelName);
adapter . set('preventSave', true);
return this.save();
}
});
Почтовый адаптер:
// adapters/post.js
export default ApplicationAdapter.extend(PreventSaveAdapter);
И модель поста:
// models/post.js
export default DS.Model.extend(PreventSaveModel, {
...
);
Используя это:
// controllers/some-controller.js
export default Ember.Controller.extend({
actions: {
someAction () {
(...)
post.saveWithoutSave();
}
}
});
Непроверенные.
Отказ от ответственности: это не идеальное решение, и я надеюсь, что кто-то может указать нам обоим в лучшем направлении.
Изменить: решение torazaburo в этой теме кажется лучшим способом.
Я столкнулся с той же ситуацией и не нашел отличного решения. В итоге я написал собственный адаптер и добавил сервис, чтобы просто вернуть true
в updateRecord
если у службы был флаг preventRequest: true
,
Пример:
// services/prevent-request.js
export default Ember.Service.extend({
prevent: false // default
});
// adapters/post.js
export default ApplicationAdapter.extend({
preventSave: Ember.inject.service(),
updateRecord (store, type, snapshot) {
if (this.get('preventSave.prevent')) {
this.set('preventSave.prevent', false);
return true;
}
this._super(store, type, snapshot);
}
});
// controllers/some-controller.js
export default Ember.Controller.extend({
preventSave: Ember.inject.service(),
actions: {
someAction () {
(...)
this.get('preventSave').set('prevent', true);
post.save();
}
}
});
Согласно Ember Guides с использованием store.createRecord()
создаст запись и добавит ее в хранилище, но не сделает запрос к бэкэнду.
Пример:
store.createRecord('post', {
title: 'Rails is Omakase',
body: 'Lorem ipsum'
});
Объект хранилища доступен в контроллерах и маршрутах с использованием this.store
,
Тогда, если вы хотите сохранить это, просто позвоните save()
,
Пример:
post.save(); // => POST to '/posts'
isDirty
означает, что запись имеет локальные изменения, которые еще не были сохранены адаптером. Это включает в себя записи, которые были созданы (но еще не сохранены) или удалены.
Грязные штаты имеют три дочерних состояния:
uncommitted
: магазин еще не передал запись для сохранения.inFlight
: хранилище передало запись для сохранения, но адаптер еще не подтвердил успешность.invalid
: запись содержит неверную информацию и пока не может быть отправлена на адаптер.
Если вы хотите сделать запись чистой, попробуйте что-то вроде этого (не проверено мной):
record.get('stateManager').send('becameClean');