Ember данные и метаданные — доступ из контроллера

Я пытаюсь получить доступ к метаданным с помощью Ember Data, используя ActiveModelAdapter. Если контроллер настроен в роутере с моделью:

App.ClaimsIndexRoute = Ember.Route.extend
  authRedirectable: true
  model: ->
    @store.findAll 'claim'

И контроллер как метаметод выглядит следующим образом:

App.ClaimsIndexController = Ember.ArrayController.extend
  meta: (->
    @store.metadataFor('claim')
  ).property()

Затем я могу получить доступ к метаданным в шаблоне индекса:

{{meta.page}} {{meta.per_page}} {{meta.total_pages}}

Но мне нужно было добавить фильтрацию. Поэтому я изменил маршрутизатор, чтобы использовать setupController:

App.ClaimsIndexRoute = Ember.Route.extend
  setupController: (controller, model) ->
    controller.loadClaims()

А в контроллере добавил функцию loadClaim:

App.ClaimsIndexController = Ember.ArrayController.extend
  loadClaims: ->
    _filter = @get 'filter'
    _result = @store.find 'claim', {filter: _filter}
    @set 'model', _result
  filter: ''
  meta: (->
    @store.metadataFor('claim')
  ).property()
  actions:
    filterClaims: ->
      @loadClaims()

Теперь метаданные больше не доступны. Я вошел в контекст с помощью отладчика и ничего не могу получить.

Есть ли проблема с отправкой запроса к Ember Data? Есть лучший способ сделать это?

Между прочим, метаданные отправляются сервером, как предложено в документации.

Я использую Ember 1.6.1 и Ember data 1.0.0-beta.8.2a68c63a.


person noel    schedule 12.09.2014    source источник
comment
Ваша проблема в том, что вы говорите controller.loadClaims() вместо controller.send('loadClaims')?   -  person Josh Padnick    schedule 13.09.2014
comment
Спасибо за предложение. Не изменил поведение.   -  person noel    schedule 15.09.2014


Ответы (1)


Вы можете попробовать несколько разных способов получения метаданных. На кофе не писал, поэтому попробую описать решения с помощью javascript.

  1. Объявите мета-свойство ClaimsIndexController в зависимости от свойства model.meta: meta: function() { return this.get('model.meta'); }.property('model.meta')

  2. Объявите мета-свойство как null и выполните его позже в обратном вызове then запроса фильтра в методе loadClaims:

    loadClaims: function () {
        var filteredClaims = this.store.find('claim', { filter: this.get('filter') }),
            self = this;
    
        filteredClaims.then(function(claims) {
            self.set('meta', claims.get('meta'));
        });
    
        this.set('model', claims);
    }
    
  3. Как видите, нет необходимости в методе loadClaims, мы можем описать модель как вычисляемое свойство и установить здесь метаданные:

    model: function () {
        var filteredClaims = this.store.find('claim', { filter: this.get('filter') }),
            self = this;
    
        filteredClaims.then(function(claims) {
            self.set('meta', claims.get('meta'));
        });
    
        return filteredClaims;
    }.property('filter')
    
  4. Или еще проще:

    model: function () {
       return this.store.find('claim', { filter: this.get('filter') });
    }.property('filter'),
    
    meta: function() {
       return this.get('model.meta');
    }.property('model.meta')
    
  5. (сомнительно) На мой взгляд, представление (шаблон) и данные должны быть максимально разделены, поэтому я бы предложил описать все поля метаданных как вычисляемые свойства контроллера:

    model: function () {
       return this.store.find('claim', { filter: this.get('filter') });
    }.property('filter'),
    
    page: function() {
       return this.get('model.meta.page');
    }.property('model.meta.page'),
    
    perPage: function() {
       return this.get('model.meta.per_page');
    }.property('model.meta.per_page'),
    
    totalPages: function() {
       return this.get('model.meta.total_pages');
    }.property('model.meta.total_pages')
    
person Microfed    schedule 13.09.2014
comment
Отличный список ответов. Я новичок в Ember, и это действительно помогает увидеть эти итерации. У меня не будет времени протестировать их в течение дня или двух, но я сделаю это. - person noel; 15.09.2014
comment
Каков правильный способ доступа к ним в представлении? Пока я не могу получить доступ к метаданным из представления, используя {{controller.meta.page}} или {{controller.page}} или {{page}}. - person noel; 16.09.2014
comment
Если я получаю доступ к хранилищу из консоли, я могу получить метаданные из хранилища с помощью store.metadataFor('claim'), но пока мне не удалось получить метаданные через модель. Документы, кажется, предполагают, что вы можете получить метаданные через результаты store.find, но я ничего не смог получить. Любые дальнейшие мысли? - person noel; 16.09.2014
comment
Метод Ember.ActiveModelSerializer.extractMeta взят из Ember.RESTSerializer (github.com/emberjs/data/blob/v1.0.0-beta.9/packages/ember-data/) и получает метаданные из свойства playload.meta. Таким образом, ember ожидает JSON типа { meta: { ... }, claims: [ ... ] } в полезной нагрузке ответа на запрос store.find('claims'). Конечно, вы можете перегрузить extractMeta meta и изменить его поведение в соответствии с другой схемой JSON. - person Microfed; 17.09.2014