Backbone collection from Json file and cache on lo

2019-02-02 18:35发布

I am relatively new in the backbone library. I'm trying to build a mobile application based on backbone + requirejs + jquery-mobile. I can fill my collection with existing json local file. (in the future may come from a remote server). Now I'm trying to get this collection to be called only once and then storing it in localStorage for read. for this I am trying to use this adapter (https://github.com/jeromegn/Backbone.localStorage) but I do not understand how.

Sample code

// models
define([
  'underscore',
  'backbone'
], function(_, Backbone) {
  var AzModel = Backbone.Model.extend({
    defaults: {
      item: '',
      img:"img/gi.jpg"
    },
    initialize: function(){
    }
  });
  return AzModel;
});

// Collection
define(['jquery', 'underscore', 'backbone', 'models/az'], function($, _, Backbone, AzModel) {
    var AzCollection = Backbone.Collection.extend({
     localStorage: new Backbone.LocalStorage("AzStore"), // Unique name within your app.       
    url : "json/azlist.json",
    model : AzModel
    parse : function(response) {
         return response;
    }
});

return AzCollection;
});

define(['jquery', 'underscore', 'backbone', 'collections/azlist', 'text!templates/karate/az.html'], function($, _, Backbone, AzList, AzViewTemplate) {
    var AzView = Backbone.View.extend({
        id:"az",
        initialize: function() {
            this.collection = new AzList(); 
            var self = this;
            this.collection.fetch().done(function() {
                //alert("done")
                self.render();
            }); 

        },
        render : function() {
            var data = this.collection;
            if (data.length == 0) {
                // Show's the jQuery Mobile loading icon
                $.mobile.loading("show");
            } else {
                 $.mobile.loading("hide");
                console.log(data.toJSON());
                  this.$el.html(_.template(AzViewTemplate, {data:data.toJSON()}));
                  // create jqueryui
                 $(document).trigger("create");
            }
            return this;
        }
    });
    return AzView;
});

Does someone can point me the way.

1条回答
淡お忘
2楼-- · 2019-02-02 19:01

The Backbone local storage adapter overrides Collection.sync, the function which is used when you fetch the collection, or save models within the collection. If you set the Collection.localStorage property, it redirects the calls to the local storage instead of the server. This means you can have either or -- read and write to local storage or server -- but not both at the same time.

This leaves you two options:

  1. Do the initial fetch, which populates the data from the server, and only then set the localStorage property:

    var self = this;
    
    self.collection.fetch().done(function() {
        self.collection.localStorage = new Backbone.LocalStorage("AzStore");
        self.render();
    }); 
    
  2. Set the Collection.localStorage property as you do now, and fetch the initial dataset manually using Backbone.ajaxSync, which is the alias given to Backbone.sync by the localstorage adapter:

    Backbone.ajaxSync('read', self.collection).done(function() {
        self.render();
    }
    

The latter option might be preferrable, because it doesn't prevent you from loading the data from the server later on, if required.

You could quite neatly wrap the functionality as a method on the collection:

var AzCollection = Backbone.Collection.extend({
    localStorage: new Backbone.LocalStorage('AzStore'),
    refreshFromServer: function() {
        return Backbone.ajaxSync('read', this);    
    }    
});

When you want to load data from the server, you can call that method:

collection.refreshFromServer().done(function() { ... });

And when you want to use the local storage, you can use the native fetch:

collection.fetch().done(function() { ... });

Edited to correct mistake in sample code for the benefit of drive-by googlers.

查看更多
登录 后发表回答