I have a backbone view which load subview. When I load a subview, I would like to show a loader when the view fetch needed datas and hide the loader when the view is ready to render.
I did something like this :
var appView = Backbone.View.extend({
showLoader: function() {
// Code to show loader
},
hideLoader: function() {
// Code to hide loader
},
loadSubView: function() {
this.showLoader();
var myView = new MySubView();
this.$el.html(myView.render().el);
this.hideLoader();
}
});
For now, my sub-view load a collection and is implemented like this :
var mySubView = Backbone.View.extend({
initialize: function() {
this.myCollection.fetch({
async: false
});
},
render: function() {
// Code to render
}
});
My sub view load the collection synchronously because it is the only way I found to know when my view is "ready" to render but I think this is not the best way to use Backbone.
What schould I do ?
There are several ways to do it.
You can explicitly use the pubsub pattern. Something like this:
var AppView = Backbone.View.extend({
showLoader: function() {
console.log('show the spinner');
},
hideLoader: function() {
console.log('hide the spinner');
},
loadSubView: function() {
this.showLoader();
var subView = new SubView();
subView.on('render', this.hideLoader);
this.$el.html(subView.render().el);
}
});
var SubView = Backbone.View.extend({
render: function() {
console.log('a subView render');
this.trigger('render');
return this;
}
});
var appView = new AppView({el: $('body')});
appView.loadSubView();
You can attach a function to the ajaxStart/ajaxStop events on the spinner itself:
var AppView = Backbone.View.extend({
initialize: function() {
var _this = this;
this.$('#spinner')
.hide()
.ajaxStart(_this.showLoader)
.ajaxStop(_this.hideLoader);
}
...
}
Or you can use jQuery.ajaxSetup
:
var AppView = Backbone.View.extend({
initialize: function() {
var _this = this;
jQuery.ajaxSetup({
beforeSend: _this.showLoader,
complete: _this.hideLoader,
success: function() {}
});
}
...
}