8
votes

I've been using Marionette for a week now and it really made my life easier!

Right now I need to be able to notify a user when a collection or model is being fetched, because some views take a significant amount of time to render/fetch. To give an example I've made a small mockup:

http://i.stack.imgur.com/IU3BP.png

When a user clicks on a category, a collection of all items within that category need to be loaded. Before The collection is fetched I want to display a loading view as seen in the image (view 1). What would be an elegant solution to implement this. I've found the following post where a user enables a fetch trigger: http://tbranyen.com/post/how-to-indicate-backbone-fetch-progress . This seems to work but not really like I wanted to. This is something I came up with:

    var ItemThumbCollectionView = Backbone.Marionette.CollectionView.extend({
        collection: new ItemsCollection(userId),
        itemView: ItemThumbView,
        initialize: function(){
            this.collection.on("fetch", function() {
                //show loading view
            }, this);
            this.collection.on("reset", function() {
                //show final view
            }, this);
            this.collection.fetch();

            Backbone.history.navigate('user/'+identifier);
            this.bindTo(this.collection, "reset", this.render, this)
        }
    });

It would be nice though If I could have an optional attribute called 'LoadItemView' for example. Which would override the itemView during a fetch. Would this be a good practice in your opinion?

4
Use collection.on('request') instead of collection.on('fetch'). And collection.fetch({reset:true}) instead of collection.fetch(). ;)Frank Fang

4 Answers

0
votes
var myCollection = Backbone.Marionette.CollectionView.extend({
    initialize: function(){
        this.collection.on('request', function() {
            //show loading here
        })
        this.collection.on('reset', function() {
            //hide loading here
        })
        this.collection.fetch({reset: true})
    }
})

It's better now, I think.

0
votes

Use Backbone sync method

/* over riding of sync application every request come hear except direct ajax */

Backbone._sync = Backbone.sync;
Backbone.sync = function(method, model, options) {
    // Clone the all options
    var params = _.clone(options);

params.success = function(model) {
    // Write code to hide the loading symbol
     //$("#loading").hide();
    if (options.success)
        options.success(model);
};
params.failure = function(model) {
    // Write code to hide the loading symbol
     //$("#loading").hide();
    if (options.failure)
        options.failure(model);
};
params.error = function(xhr, errText) {
    // Write code to hide the loading symbol
     //$("#loading").hide();
    if (options.error)
        options.error(xhr, errText);
};
// Write code to show the loading symbol
     //$("#loading").show();
Backbone._sync(method, model, params);

};

0
votes

In general, I'd suggest loading a preloader while fetching data, then showing the collection. Something like:

region.show(myPreloader);
collection.fetch().done(function() {
    region.show(new MyCollectionView({ collection: collection });
});