Подтвердить что ты не робот

Доступ к метаинформации, переданной в ответ json-сервера

Я использую Ember-Data Rest-Adapter, а JSON, возвращаемый с моего сервера, выглядит в основном так же, как в Документация по серийным файлам Active Model

{
  "meta": { "total": 10 },
  "posts": [
    { "title": "Post 1", "body": "Hello!" },
    { "title": "Post 2", "body": "Goodbye!" }
  ]
}

Получение данных с сервера работает, но, к сожалению, я не могу понять, где я могу получить доступ к метаинформации из моего ответа JSON.

Основываясь на моих исследованиях в github ember-data, поддержка метаинформации представляется реализована с фиксацией 1787bff.

Но даже с тестовыми примерами я не смог понять, как получить доступ к метаинформации.

App.PostController = Ember.ArrayController.extend({
   ....
   requestSearchData: function(searchParams){
      posts = App.Post.find(searchParams);
      this.set('content', posts);
      // don't know how to access meta["total"]
      // but I want to do something like this:
      // this.set('totalCount', meta["total"])
   }
})

Может кто-нибудь из вас пролить свет на это для меня, пожалуйста? Я знаю, что Ember api движется быстро, но я уверен, что я просто пропустил небольшую часть и что это действительно возможно.

4b9b3361

Ответ 1

Я нашел более чистый подход для извлечения метаинформации из ответа сервера с помощью ember-данных.

Мы должны сказать сериализатору, какая метаинформация должна ожидать (в данном случае разбивка на страницы):

 App.serializer = DS.RESTSerializer.create();

 App.serializer.configure({ pagination: 'pagination' });

 App.CustomAdapter = DS.RESTAdapter.extend({
   serializer: App.serializer
 });

 App.Store = DS.Store.extend({
   adapter: 'App.CustomAdapter'
 });

После этого каждый раз, когда сервер отправляет мета-свойство с объектом разбивки на страницы, этот объект будет добавлен в свойство store TypeMaps для запрашиваемого модельного класса.

Например, со следующим ответом:

  {
    'meta': {'pagination': { 'page': 1, 'total': 10 } },
    'posts':[
      ...
    ]
  }

TypeMap для App.Post-Model будет включать объект разбивки на страницы после загрузки сообщений.

Вы не можете напрямую наблюдать свойство TypeMaps в хранилище, поэтому я добавил вычисляемое свойство PostsController для доступа к метаинформации с разбивкой на запросы:

 App.PostsController = Ember.ArrayController.extend({
    pagination: function () {
      if (this.get('model.isLoaded')) {
        modelType = this.get('model.type');
        this.get('store').typeMapFor(modelType).metadata.pagination
      }
    }.property('model.isLoaded')
 });

Я действительно не думаю, что отличное решение проблемы метаинформации, но это лучшее решение, с которым я смог придумать Ember-Data. Возможно, в будущем это будет проще.

Ответ 2

Я выяснил способ доступа к метаинформации, переданной в ответе. Но, к сожалению, это действительно не поддерживается ember-данными из коробки, и я пишу метаинформацию в глобальную переменную, которую я получаю через привязки в запрашивающем контроллере.

Я закончил настройку сериализатора, который использует RESTAdapter:

App.CustomRESTSerializer = DS.RESTSerializer.extend({
  extractMeta: function(loader, type, json) {
    var meta;
    meta = json[this.configOption(type, 'meta')];
    if (!meta) { return; }
    Ember.set('App.metaDataForLastRequest', meta);
    this._super(loader, type, json);
  }
});

App.Store = DS.Store.extend({
  revision: 11,
  adapter: DS.RESTAdapter.create({
    bulkCommit: false,
    serializer: App.CustomRESTSerializer
  })
});

Я знаю, что это не особенно красиво и на самом деле думает, что это противоречит тому, что ожидаются нам данные ember-данных, но пока он работает правильно.

Я попытаюсь улучшить работу с ember-данными и отправить запрос на перенос, когда он работает, или открыть проблему в github, когда кто-либо еще заинтересован в том, чтобы это работало.

Если кто-нибудь найдет более чистое решение, пожалуйста, дайте мне знать.

Ответ 3

Я думаю, что немедленное исправление для вас - это привязать totalCount к вашей модели (recordArray), посмотрите thread.

Еще один способ - создать собственный адаптер:

DS.Adapter.create({
  find: function (store, type, id) {
    $.ajax({
      url:      type.url,
      dataType: 'jsonp',
      context:  store,
      success:  function(response){
        this.load(type, id, response.data);
      }
    });
  },
  findAll: function(store, type) {
    $.ajax({
      url:      type.url,
      dataType: 'jsonp',
      context:  store,
      success:  function(response){
        this.loadMany(type, response.data);
      }
    });
  }
});

Параметр ответа при успешном обратном вызове в методе findAll должен быть тем, который вам нужен:

response: {
  meta: {
    totalCount: 10
  },
  posts: [{}, {}]
}

Надеюсь, что это поможет.