BackboneJS - How to add a Progressbar while fetchi

2019-06-09 06:55发布

问题:

I have an Backbone App where I fetch different collections by clicking a Letter from a list. So, I want to add a Progressbar or some kind of rotating image but I dont know how to do this.

My View looks like this

function (App, Backbone) {

    var Artists = App.module();
    var ArtistView = Backbone.View.extend({
        tagName : 'li',
        template: 'artistItem',
        serialize: function() {
            var data = this.model.toJSON();
            data.letter = this.model.collection.letter;

            return data;
        },  
    });

    Artists.View = Backbone.View.extend({
        tagName  : 'ul',
        className : 'artistList',
        initialize: function() {
            this.listenTo(this.collection, 'all', this.render);
            this.listenTo(App, 'navigateLetter', this.updateState);
        },
        beforeRender: function() {
            var self = this;

            this.collection.each(function(item) {
                self.insertView(new ArtistView({model: item}))
            })
        },
        updateState: function(letter) {
            this.collection.letter = letter;
            this.stopListening(this.collection);
            this.collection.fetch();
            this.listenTo(this.collection, 'all', this.render);
        }   
    });
    Artists.ArtistsCollection = Backbone.Collection.extend({
        url: function() {
            return '/projects/mdk/index.php/api/artists/' + this.letter; 
        }
    });

    return Artists;
});

So does anyone have an idea how to do this? I could imagine I should do something in initialize or beforeRender?

Thanks in advance

回答1:

You can use a spinner for the loading effect. For that you need

spin.js

Add entry of that spin.js into main file.

To use that spinner.

var yourSpinner = new Spinner();
var target = document.getElementById('spinHere');
yourSpinner.spin(target);

e.g in your case take updateState:function(){} :

updateState: function(letter) {
    this.collection.letter = letter;
    this.stopListening(this.collection);
    var yourSpinner = new Spinner();
    var target = document.getElementById('spinHere');
    yourSpinner.spin(target);
    this.collection.fetch();
    yourSpinner.stop();
    this.listenTo(this.collection, 'all', this.render);
}


回答2:

Take a look at this: https://github.com/davidsulc/marionette-gentle-introduction/blob/master/assets/js/apps/contacts/list/list_controller.js#L4

It's from my Marionette book app, where the idea is to immediately display a loading view, and when the collection is fetched, render the actual view (and closing the loading view, which is Handled by Marionette). It would give something like (pseudocode):

  var loadingView = new ContactManager.Common.Views.Loading();
  ContactManager.mainRegion.show(loadingView);

  var fetchingContacts = myCollection.fetch();

  $.when(fetchingContacts).done(function(contacts){
    ContactManager.mainRegion.show(new MyCollView({ collection: contacts }));
  });

The code uses a deferred to determine when the collection has been fetched (and therefore the new view should be displayed). You can learn more about using deferreds here:

  • http://davidsulc.com/blog/2013/04/01/using-jquery-promises-to-render-backbone-views-after-fetching-data/
  • http://davidsulc.com/blog/2013/04/02/rendering-a-view-after-multiple-async-functions-return-using-promises/


标签: backbone.js