Backbone.js progress bar while fetching collection

2019-03-20 03:47发布

i'd like to show a progress bar while i update the app with fresh content. I guess the best thing to do would be to do it while calling .fetch on a collection.

The content i fetch is primarily images (video poster etc) but i only get the link, not a base64 string or something big. What i would like to do is overlay the screen with a progress bar while fetching the image links, render the view so all images are ready and then the overlay should go away and show the app with the fresh content already loaded.

Now i have no idea how i could build a progress bar for this since i am not really getting images directly but only the link and then rendering the view.

6条回答
Lonely孤独者°
2楼-- · 2019-03-20 03:52

You could use jQuery ajaxStart and ajaxStop to show the progress on start and hide it on end. Doing it this way, however, will show your indicator any time and ajax request is made on your page.

A route you could take if you want to limit it to just that particular fetch would be to override the sync method in that collection or model and wrap the default sync with some code that shows and hides the progress bar.

查看更多
乱世女痞
3楼-- · 2019-03-20 03:55

Try this:

var SomeView = Backbone.View.extend({
    loadStuff: function(){
        var self = this;
        someModel.fetch({
            xhr: function() {
                var xhr = $.ajaxSettings.xhr();
                xhr.onprogress = self.handleProgress;
                return xhr;
            }
        });
    },
    handleProgress: function(evt){
        var percentComplete = 0;
        if (evt.lengthComputable) {  
            percentComplete = evt.loaded / evt.total;
        }
        //console.log(Math.round(percentComplete * 100)+"%");
    }
});
查看更多
太酷不给撩
4楼-- · 2019-03-20 03:56

Overwrite backbone sync method, instead of writing every place add it to sync method. It will work for new pages without writing any new code.

查看更多
劫难
5楼-- · 2019-03-20 03:58

When you call fetch put up your loading bar.

Then pass a function as options.success to the fetch method (docs) that takes it the screen.

Or, when you render your objects to the screen you can pull it down then.

We use this for one of our views and just pull it off using the options.success method

查看更多
萌系小妹纸
6楼-- · 2019-03-20 04:00

Here's some steps that might work out.

  1. when the fetch starts (maybe using ajaxStart or whatever), bring up your pop-over.
  2. when the fetch finishes, identify or create the image urls from the JSON and use one of the several image preloaders out there that have a callback whenever all the images are loaded. If you want to make that yourself, I'd say this would be the psuedocode for that:
    1. Push all your images to an array imagesurls. (this will be an array of strings).
    2. Capture the array length into a variable imagesleft.
    3. Create a function var imageOnLoad = function () {...} capturing that variable which
      1. decrements imagesleft by 1
      2. Does whatever it needs to to update the popover
      3. if imagesleft reaches 0, invoke the code/method to cause the popover to eventually go away
    4. For each of the strings imagesurls[i] in the imagesurls array
      1. create a new Image object. var img = new Image();
      2. img.onload = imageOnLoad;
      3. img.src = imagesurls[i];

Of course I'm ignoring error situations (Images have an onerror property you could assign similarly and the original ajax could fail). but I think the gist of a solution is there. The only thing I'm wondering about is whether or not you actually need to keep a reference to each of the images objects as they're being created. It might be a good idea, at least until you are done with the whole image set. Otherwise, I'd have to worry about garbage collection somehow interfering in some implementation... but then maybe I'm just being paranoid.

查看更多
爷、活的狠高调
7楼-- · 2019-03-20 04:15

Before you fetch the collection put up the progress bar. When the collection is done and you are rendering the images to the DOM add listeners to the image load events. When all the images have successfully loaded remove the progress bar.

You will want to make sure you are also listening for load failures incase an image doesn't load since the progress bar would never get removed in that case.

查看更多
登录 后发表回答