Я хотел бы использовать локальное хранилище HTML5 с моим Ember.js.
Я не смог найти никаких примеров этого без Ember Data.
Как это сделать? Что мне нужно учитывать?
Я хотел бы использовать локальное хранилище HTML5 с моим Ember.js.
Я не смог найти никаких примеров этого без Ember Data.
Как это сделать? Что мне нужно учитывать?
Итак, скажем, у нас есть объект с именем 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
Надеюсь, что это поможет.
Принятый ответ велик, но я подумал, что добавлю эту альтернативу:
Дэн Гебхардт создал очень интересную библиотеку под названием Orbit.js для координации различных источников данных на клиенте. Существует три источника данных: память, локальное хранилище и json api.
Для интеграции с ember проверьте ember-orbit.
В настоящее время он все еще находится в тяжелом развитии, и он вводит другую парадигму, чем Ember Data, поэтому будьте осторожны!