简体   繁体   中英

How do I know my collection already has data using Backbone.JS?

I am developing a site using javascript framework BACKBONE.JS. In my site, There is one Category Selection drop down. Using Backbone collection fetch, I have rendered my category drop down successfully. In my header i have three horizontal menu[image shown below]. User click of the menu(Page navigation is done using backbone routers). My main content of the day will change. The user can filter the content based on the category. My category filter drop down option will not change frequently.

水平菜单

My Router:

dealapp.AppRouter = Backbone.Router.extend({
    routes: {
        "": "home",
        "all/mobile": "mobile",
        "all/descktop": "displayAllVoucher"
    },
    home: function () {},
    mobile: function () {},
    desktop: function () {}
});

Success Case

I am loading my site Using " http://www.Site1.com/ ". The function home will get a call and do the listed action. If i am navigating to some other tab(mobile/desktop), my category drop down displaying.[ Note : i am fetching my category from the server in the home function]

scenario

I am loading my site using " http://www.Site1.com/#all/deal " directly. In this case my category drop down is not rendering , i am getting an empty drop down. I know that i haven't added my category fetch in the other two functions mobile and desktop. If i include the category fetch in mobile and desktop function each time then my category fetch call goes to server and fetches data from server.

My doubt

How do i know if my collection already has data? I want to reuse the already downloaded data. If data not available in the local storage then i need to fetch it from the server.

You can override fetch on the collection. Fetch returns a deferred object, you can store this on the collection itself. If the deferred is null you will call the prototype fetch. The advantage is that in your code you always call fetch, and if the collection has data you return the cached data.

fetch : function(options) {
  if(this.deferred){
    return this.deferred;
  }
  this.deferred = Backbone.Collection.prototype.fetch.call(this, options);
  return this.deferred;
}

This specific problem was dealt with by others and a few plugins can be found.

The one I am currently using with success is the Thorax framework that adds a few things over Backbone.

For Model and Collection they added isPopulated() and isEmpty() method as can be seen here in their documentation .

They will tell you if there is data in the collection or not. If you don't want to use the entire framework, just copying the code from their Git repository here , would do.

In a few words they solve the problem by overriding fetch to set a property called _fetched to true when the data are fetched.


Another way would be to cache the data. Most of the time this is a good idea, but this depends. In your scenario it could be a good idea to cache it in a localStorage.

A plugin I found that seems to do it's job is Backbone fetch cache .

Description:

This plugin intercepts calls to fetch and stores the results in a cache object (Backbone.fetchCache._cache). If fetch is called with { cache: true } in the options and the URL has already been cached the AJAX call will be skipped.


Yet another version is mentioned in this answer: Caching collections in backbone.js?

As the answerer there said, you could do it similar to this:

var manager = (function(){

  var constructors = {
    'example': ExampleCollection
  };
  var collections = {};

  return {
    getCollection: function(name) {
      if(!collections[name]) {
        var collection = new constructors[name]();
        collection.fetch();
        collections[name] = collection;
      }
      return collections[name];
    }
  }
})();

Here the manager is responsible for instantiating collections and fetching them. When you call:

 var exampleCollection = manager.getCollection('example'); 

you get an instance of example collection with data being already fetched. Whenever you need this collection again you can call the method again. You will then get the exact same instance with no need to fetch it again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM