如何在Ember.js中使用HTML5本地存储?

时间:2013-08-30 08:57:23

标签: html5 ember.js local-storage

我想在我的Ember.js中使用HTML5本地存储。

如果没有Ember Data,我无法找到任何这样做的例子。

应该怎么做?我需要考虑什么?

2 个答案:

答案 0 :(得分:22)

因此,假设我们有一个名为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-feature for that”,名为Application.initializer,初始化程序是简单的类,带有'name'属性和initialize函数,您可以在其中访问您的应用程序container和做任何需要做的事情,让我在代码中解释一下:

要在应用程序开始加载时收到通知,我们可以收听onLoad事件,以创建我们的初始化程序类,将registerinject前面提到的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

希望它有所帮助。

答案 1 :(得分:1)

接受的答案很棒,但我想我会添加这个替代方案:

Dan Gebhardt创建了一个非常有趣的库Orbit.js,用于协调客户端上的不同数据源。有三个开箱即用的数据源:内存,本地存储和json api。

对于ember集成,请查看ember-orbit

此时它仍处于重大发展阶段,它引入了与Ember Data不同的范例,所以请谨慎行事!