En En

Помещение записей в хранилище


Хранилище можно воспринимать как кэш всех записей, которые загрузило приложение. Когда маршрут или контроллер в приложении запрашивает запись, хранилище может вернуть ее сразу, если она находится в кэше. В противном случае хранилище должно обратиться к адаптеру, чтобы он загрузил запись. Обычно это значит путешествие по сети для извлечения записи с сервера.

Вместо того чтобы ожидать, пока приложение запросит запись, вы можете заранее поместить записи в кэш хранилища.

Это полезно, если вы хорошо знаете, какие записи понадобятся пользователю. Когда он нажимает ссылку, вместо ожидания, пока завершится сетевой запрос, Ember.js может немедленно отобразить новый шаблон. Создается ощущение, что все происходит мгновенно.

Еще это можно использовать, когда приложение имеет потоковое соединение с backend'ом. Тогда, если запись создают или изменяют, интерфейс пользователя обновляется сразу.

Помещение записей

Чтобы поместить запись в хранилище, вызовите метод хранилища push().

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

Мы можем использовать route:application, чтобы сделать это. route:application — верхний маршрут в иерархии, и его hook model запускается при начальной загрузке приложения.

app/models/album.js

import DS from 'ember-data';

export default DS.Model.extend({
  title: DS.attr(),
  artist: DS.attr(),
  songCount: DS.attr()
});

app/routes/application.js

import Ember from 'ember';

export default Ember.Route.extend({
  model() {
    this.get('store').push({
      data: [{
        id: 1,
        type: 'album',
        attributes: {
          title: 'Fewer Moving Parts',
          artist: 'David Bazan',
          songCount: 10
        },
        relationships: {}
      }, {
        id: 2,
        type: 'album',
        attributes: {
          title: 'Calgary b/w I Can\'t Make You Love Me/Nick Of Time',
          artist: 'Bon Iver',
          songCount: 2
        },
        relationships: {}
      }]
    });
  }
});

Метод хранилища push() — API низкого уровня. Он принимает документ JSON API, который имеет несколько важных отличий от документа JSON API, что принимает JSONAPISerializer. Имя типа в документе JSON API должно в точности соответствовать имени типа модели (в примере выше тип — album, так как модель определена в app/models/album.js). Имена атрибутов и связей должны соответствовать стилю свойств, которые определены в классе модели.

Если вы хотите, чтобы исходный сериализатор модели стандартизировал данные, прежде чем помещать их в хранилище, то можете использовать метод store.pushPayload().

app/serializers/album.js

import DS from 'ember-data';

export default DS.RestSerializer.extend({
  normalize(typeHash, hash) {
    hash['songCount'] = hash['song_count']
    delete hash['song_count']
    return this._super(typeHash, hash);
  }

})

app/routes/application.js

import Ember from 'ember';

export default Ember.Route.extend({
  model() {
    this.get('store').pushPayload({
      albums: [
        {
          id: 1,
          title: 'Fever Moving Parts',
          artist: 'David Bazan',
          song_count: 10
        },
        {
          id: 2,
          title: 'Calgary b/w I Can\'t Make You Love Me/Nick Of Time',
          artist: 'Bon Iver',
          song_count: 2
        }
      ]
    });
  }
});

Метод push() также важен при работе со сложными конечными точками. Возможно, ваше приложение имеет конечную точку, которая реализует некоторую бизнес-логику при создании нескольких записей. Это не соответствует в точности существующему API save() в Ember Data, который организован для сохранения одной записи. Вместо этого вам следует выполнить собственный запрос AJAX и поместить полученные данные модели в хранилище. Так они будут доступны для других частей приложения.

app/routes/confirm-payment.js

import Ember from 'ember';

export default Ember.Route.extend({
  actions: {
    confirm: function(data) {
      $.ajax({
        data: data,
        method: 'POST',
        url: 'process-payment'
      }).then((digitalInventory) => {
        this.get('store').pushPayload(digitalInventory);
        this.transitionTo('thank-you');
      });
    }
  }
});

Свойства, которые определены в модели, но опущены в стандартизированном объекте документа JSON API, не будут обновлены. Свойства, которые включены в стандартизированный объект документа JSON API, но не определены в модели, будут проигнорированы.


Комментарии (3)

  1. Алексей 30 мая 2016, 19:07 # 0
    Кажется, статья устарела. В документации к 2.5.0 нет
    DS.attr()
    но есть
    import attr from 'ember-data/attr';
    и вызовы
    attr()
    1. Александр 07 июня 2016, 08:23 # 0
      Да, все верно.
      Фреймворк очень быстро меняется, не успеваем за ним.
      Скоро все статьи будем обновлять.
      1. Дмитрий 04 августа 2016, 16:48 # 0
        По сути эт одно и то же, поскольку в свежем варианте предлагает импортировать не DS from 'ember-data', а только лишь attr from 'ember-data/attr' — и синтаксис обращения через точку упростился
      Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.