Как получить доступ к мета-ключу верхнего уровня из ответа 200 сервера json-api при вызове destroyRecord() данных Ember

Я работаю над приложением Ember, которое использует данные Ember и адаптер json-api по умолчанию.

Согласно спецификации json-api (http://jsonapi.org/format/#crud-deleting) при удалении записи ваш сервер должен вернуть ответ 200, если удаление прошло успешно, и сервер отвечает только ключом верхнего уровня meta.

Мой текущий сервер делает именно это, и я пытаюсь выяснить, как получить доступ к данным в метаобъекте верхнего уровня при использовании метода model.destroyRecord() Ember Data.

myModel.destroyRecord().then(function(model){
    // the returned value is the model.  How can I get the actual metadata 
    // returned by the server?   
});

Ответ сервера содержит информацию о том, что именно было удалено, и выглядит так:

{
   "meta": {
      num-deleted-a: 10,
      num-deleted-b: 100,
      num-deleted-c: 200
    }
}

Я хотел бы получить эту информацию, чтобы я мог показать ее пользователю.

Спасибо!

Я использую следующие версии:

Ember             : 2.2.0
Ember Data        : 2.3.3
jQuery            : 1.11.3

person Sarus    schedule 19.02.2016    source источник


Ответы (2)


Ember не поддерживает meta для запросов одной модели (find, save и destroyRecord) на данный момент!

Если вы хотите этого, вы должны подключиться к внутренностям Ember.

Следующий код использует внутренности ember из ember 2.3 и может работать некорректно в будущих версиях!

На store есть недокументированная функция _metadataFor, которая дает вам последние метаданные для данного типа. Я использую собственный инициализатор, чтобы всегда сохранять его в Model:

import Ember from 'ember'; 
import DS from 'ember-data';
const {set} = Ember;
export function initialize(application) {
  DS.Model.reopen({
    meta: null,
    didCommit() {
      this._super(...arguments);
      set(this, 'meta', this.store._metadataFor(this.constructor.modelName));
    }
  });
};

export default {
  name: 'meta',
  initialize: initialize
};

После этого вы можете сделать model.save().then(() => console.log(model.get('meta'))) или model.destroyRecord.then(() => console.log(model.get('meta'))).

Возможно, проверьте этот ember-twiddle.

person Lux    schedule 24.02.2016
comment
Спасибо и извините за поздний ответ! Я наткнулся на свойство _metadataFor при отслеживании кода и смог его использовать. Мне нравится, как вы добавили его прямо в модель. - person Sarus; 02.03.2016
comment
Просто к сведению людей, которые используют Ember 2.6. Это больше не работает. - person Sarus; 11.07.2016

После обновления до Ember 2.6.1 и Ember 2.6.1 я больше не мог получить доступ к свойству store._metadataFor.

Чтобы получить доступ к метаданным из определенного вызова, я теперь переопределяю сериализатор для модели и добавляю свойство meta к самой модели, которое просто проходит через метаданные.

В качестве примера у меня есть тип записи с именем vote, который при сохранении возвращает некоторые метаданные.

Для модели я делаю следующее:

// Vote Model (/app/models/vote)
export default DS.Model.extend({
  vote: DS.attr('number'),
  // Since i don't provide a transform the values for meta are passed through in
  // raw form
  meta: DS.attr()
});

Затем в сериализаторе для модели голосования я делаю следующее:

// Vote serializer (/app/serializers/vote)
import DS from "ember-data";

export default DS.JSONAPISerializer.extend({
  normalizeSaveResponse(store, primaryModelClass, payload, id, requestType) {
    // The metadata in the payload does get processed by default and will be
    // placed into a top level `meta` key on the returned documentHash
    let documentHash = this._super(store, primaryModelClass, payload, id, requestType);

    // Make sure we always have an empty object assigned to the meta attribute
    if(typeof(payload.meta) !== 'object'){
      payload.meta = {};
    }

    // Move the metadata into the attributes hash for the model
    documentHash.data.attributes.meta = payload.meta;

    return documentHash;
  }
});

Обратите внимание, что в приведенном выше примере я добавляю метаданные в модель голосования только при вызове сохранения в хранилище. Если вы хотите всегда добавлять метаданные, вы должны переопределить метод normalize вместо метода normalizeSaveResponse.

Затем вы можете получить доступ к полю meta в результатах вашего вызова сохранения.

let vote = self.store.createRecord('vote', {
   vote: voteValue
});

vote.save().then(function(result){
   // this will now contain your metadata
   console.info(result.get('meta'));
});
person Sarus    schedule 11.07.2016
comment
normalizeResponse(store, primaryModelClass, payload, id, requestType) { payload.data.attributes.meta = payload.meta || {}; вернуть this._super.apply (это, аргументы); } // См.: guides.emberjs.com/v2. 1.0/модели/настройка-сериализаторы/ - person GK100; 19.04.2017