我想在 Ember.js 中使用 HTML5 本地存储。
如果没有 Ember Data,我找不到任何这样做的例子。
这应该怎么做?我需要考虑什么?
我想在 Ember.js 中使用 HTML5 本地存储。
如果没有 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
挂钩中使用它来检索它,只是为了证明它有效。
现在更棒的是,您可以在应用程序准备好后直接执行register
& inject
,但是如果我们希望它在应用程序初始化时已经可用怎么办?好吧,“有一个 ember 特性”,称为Application.initializer
初始化程序,它们是具有“名称”属性和一个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 方式和一些虚构的延迟,而不仅仅是返回数组):
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
希望能帮助到你。
接受的答案很好,但我想我会添加这个替代方案:
Dan Gebhardt 创建了一个非常有趣的库,称为Orbit.js,用于协调客户端上的不同数据源。有三种开箱即用的数据源:内存、本地存储和 json api。
对于 ember 集成,请查看ember-orbit。
它目前仍在大力开发中,并且引入了与Ember Data不同的范式,因此请谨慎行事!