Caching remote data in Local Storage with EmberData

前端 未结 3 1902
暖寄归人
暖寄归人 2021-01-30 16:32

I have a question about loading and caching remote objects with Ember. I\'m developing an Ember app that uses server-side storage through a REST API. Some of the fetched data is

3条回答
  •  隐瞒了意图╮
    2021-01-30 17:22

    Here's a way to do it. A mixin for your adapters, with a method localStoreRecord you can use to cache the record, lastly an initializer to preload the store.

    Local Storage is simply a key:value store for stringified objects, so we can store all of our application data under a single key.

    Note: this is using es6 modules

    // app/mixins/local-storage.js
    
    import Ember from 'ember';
    
    export default Ember.Mixin.create({
      appName: 'myApp',
      // how many records per model to store locally, can be improved.
      // needed to prevent going over localStorage's 5mb limit
      localStorageLimit: 5,
      localStoreRecord: function(record) {
        var data = JSON.parse(localStorage.getItem(this.appName));
        data = data || {};
        data[this.modelName] = data[this.modelName] || [];
        var isNew = data[this.modelName].every(function(rec) {
          rec.id !== record.id; 
        });
        if (isNew) {
          data[this.modelName].push(record);
          if (data[this.modelName].length > this.localStorageLimit) {
            data[this.modelName].shift();
          }
          localStorage.setItem(this.appName, JSON.stringify(data));
        }
      }
    });

    // app/adapters/skateboard.js
    
    import DS from 'ember-data';
    import Ember from 'ember';
    import LocalStorageMixin from '../mixins/local-storage';
    
    export default DS.RESTAdapter.extend(LocalStorageMixin, {
      modelName: 'skateboard',
      find: function(store, type, id) {
        var self = this;
        var url = [type,id].join('/');
        return new Ember.RSVP.Promise(function(resolve, reject) {
          Ember.$.ajax({
            url: 'api/' + url,
            type: 'GET'
          }).done(function (response) {
            // cache the response in localStorage
            self.localStoreRecord(response);
            resolve({ type: response });
          }).fail(function(jqHXR, responseStatus) {
            reject(new Error(type +
             ' request failed with status=' + reponseStatus);  
          });
        });
      },
      updateRecord: function(store, type, record) {
        var data = this.serialize(record, { includeId: true });
        var id = record.get('id');
        var url = [type, id].join('/');
        return new Ember.RSVP.Promise(function(resolve, reject) {
          Ember.$.ajax({
            type: 'PUT',
            url: 'api/' + url,
            dataType: 'json',
            data: data
          }).then(function(data) {
            // cache the response in localStorage
            self.localStoreRecord(response);
            resolve({ type: response });
          }).fail(function(jqXHR, responseData) {
            reject(new Error(type +
             ' request failed with status=' + reponseStatus);
          });
        });
      }
    });
    

    // app/initializers/local-storage.js
    
    export var initialize = function(container/*, application*/) {
      var appName = 'myApp';
      var store = container.lookup('store:main');
      var data = JSON.parse(localStorage.getItem(appName));
      console.log('localStorage:',data);
      if (!data) {
        return;
      }
      var keys = Object.keys(data);
      if (keys.length) {
        keys.forEach(function(key) {
          console.log(key,data[key][0]);
          store.createRecord(key, data[key][0]);
        });
      }
    };
    
    export default {
      name: 'local-storage',
      after: 'store',
      initialize: initialize
    };

提交回复
热议问题