Как использовать локальное хранилище HTML5 с Ember.js?

Я хотел бы использовать локальное хранилище HTML5 с моим Ember.js.

Я не смог найти никаких примеров этого без Ember Data.

Как это сделать? Что мне нужно учитывать?

Ответ 1

Итак, скажем, у нас есть объект с именем Storage, который в нашей реальной реализации будет представлять собой объект типа адаптера для localStorage для хранения и извлечения данных:

App.Storage = Ember.Object.extend({
  init: function() {
    this.clearStorage();

    var items = ['foo', 'bar', 'baz'];
    localStorage.items = JSON.stringify(items);
  },
  find: function(key) {
    // pseudo implementation
    if( !Ember.isNone(key) ) {
      var items = [];
      var storedItems = JSON.parse(localStorage[key]);
      storedItems.forEach(function(item){
        items.pushObject(item);
      });
      return items;
    }
  },
  clearStorage: function() {
    // pseudo implementation
    localStorage.clear();
  }
});

Помимо псевдо-реализации, вы можете увидеть, что есть фиктивный массив с некоторыми данными, хранящимися при инициализации объекта, мы будем использовать это позже в нашем IndexRoute model hook для его получения, чтобы показать, что это работает.

Теперь к более приятным материалам вы можете сделать register и inject непосредственно после того, как приложение будет готово, но что, если мы хотим, чтобы он уже был доступен при инициализации приложения? Ну, "там функция ember-feature", называемая Application.initializer, инициализатор - это простые классы с свойством "name" и функцией initialize, в которой у вас есть доступ к вашему приложению container, и делайте то, что когда-либо должно быть сделайте, позвольте мне объяснить это в коде:

Чтобы получать уведомления о начале загрузки приложения, мы можем прослушать событие onLoad, чтобы создать наши классы инициализатора, которые будут register и inject ранее упомянутого объекта Storage в каждом контроллере и каждом маршруте:

Ember.onLoad('Ember.Application', function(Application) {
 // Initializer for registering the Storage Object
  Application.initializer({
    name: "registerStorage",
    initialize: function(container, application) {
      application.register('storage:main', application.Storage, {singleton: true});
    }
  });
 // Initializer for injecting the Storage Object
  Application.initializer({
    name: "injectStorage",

    initialize: function(container, application) {
      application.inject('controller', 'storage', 'storage:main');
      application.inject('route', 'storage', 'storage:main');
    }
  });
});

Теперь, поскольку объект Storage был введен в каждый маршрут и каждый контроллер, мы можем, наконец, получить доступ к нему в нашем IndexRoute model и сделать массив, упомянутый выше, доступным через вызов self.get('storage').find('items') наш шаблон будет визуализирован (просто добавлено обещание сделать его на самом деле совместимым с ember-way и с некоторой фиктивной задержкой, а не просто возвратом массива):

App.IndexRoute = Ember.Route.extend({
  model: function(){
    var self = this;
    var promise = new Ember.RSVP.Promise(function(resolve) {
      Ember.run.later(function() {
        var data = self.get('storage').find('items');
        console.log(data);
        resolve(data);
      }, 1000);
    });

    return promise;
  }
});

В нашем шаблоне index мы можем теперь агностически перебирать фиктивный массив, не заботясь о том, откуда он идет:

<script type="text/x-handlebars" id="index">
  <h2>Index</h2>
  <ul>
    {{#each item in model}}
      <li>Item: {{item}}</li>
    {{/each}}
  </ul>
</script>

И, наконец, вы можете увидеть здесь все приведенное выше в рабочем примере: http://jsbin.com/eqAfeP/2/edit

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

Ответ 2

Принятый ответ велик, но я подумал, что добавлю эту альтернативу:

Дэн Гебхардт создал очень интересную библиотеку под названием Orbit.js для координации различных источников данных на клиенте. Существует три источника данных: память, локальное хранилище и json api.

Для интеграции с ember проверьте ember-orbit.

В настоящее время он все еще находится в тяжелом развитии, и он вводит другую парадигму, чем Ember Data, поэтому будьте осторожны!