Как сохранить запись 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'); 
Другие вопросы по тегам