How to bind list of images using knockout in page with loading spinner

大憨熊 提交于 2019-12-13 04:37:13

问题


I have been searching Google to get some ideas and I found some code but it's incomplete and hard to understand. I want to use knockout to bind a list of images.

What's the best way to set up a spinner background while the images are loading. I have a spinner class I can set and unset to the background image.

Here is the code but it's not clear

 ko.bindingHandlers.Loading = {
        update: function (element, valueAccessor, allBindingsAccessor) {
            var value = valueAccessor(), allBindings = allBindingsAccessor();
            var valueUnwrapped = ko.utils.unwrapObservable(value);

            if (valueUnwrapped == true)
                $(element).showLoading(); // Make the element visible
            else
                $(element).hideLoading();   // Make the element invisible
        }
    };

and then use it like

<div data-bind="Loading: isLoading" >

update

    <img src="http://www.aero-sa.com/images/ajax-loader.gif" data-bind="visible:loading" />
var model = function() {
    var self = this;
    this.loading =  ko.observable(true);
    setTimeout(function() {
        self.loading(false);
    }, 4000);
}
ko.applyBindings(new model());

i have few question on the above code. what is this here? this point to what? when i write the code like then image is not getting hide....why this is not working.

var model = function() {
        //var self = this;
        this.loading =  ko.observable(true);
        setTimeout(function() {
            this.loading(false);
        }, 4000);
    }
    ko.applyBindings(new model());

please explain if possible.


回答1:


I had a similar problem. In my case, I needed to hide a whole block of HTML if an image inside the block could not be loaded. I ended up using the imagesLoaded library (https://github.com/desandro/imagesloaded), which I wrapped in a knockout custom binding :

function tryRegisterEvent(imgLoad, event, handler) {
    if (handler === undefined) return;

    imgLoad.on(event, handler);
}

function tryRegisterEvents(imgLoad, events, bindings) {
    for (var i = 0; i < events.length; ++i) {
        var event = events[i];
        tryRegisterEvent(imgLoad, event, bindings[event]);
    }
}

ko.bindingHandlers['imagesLoaded'] = {
    'init': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        if (imagesLoaded === undefined) {
            throw new Error('imagesLoaded is not defined');
        }

        var bindings = ko.utils.unwrapObservable(valueAccessor());

        var imgLoad = imagesLoaded(element);

        tryRegisterEvents(imgLoad, ['always', 'done', 'fail', 'progress'], bindings);
    },
    'update': function () {}
};

Then I could use this binding in my HTML, as follow:

<div data-bind="visible: isLoading() || isLoaded()">
    Some more HTML and text...
    <img src="..." data-bind="imagesLoaded: { done: function () { isLoaded(true); }, always: function () { isLoading(false); } }" />
</div>

I initially set isLoading to true and isLoaded to false, and the event handlers would then change my view model's state accordingly, based on the image load status.

Note that since the imagesLoaded library can work with container instead of single images (and monitor all images inside the container), you can use this custom binding on a parent element containing all your image gallery, then display your spinner and hide it when the always event is triggered.



来源:https://stackoverflow.com/questions/17590336/how-to-bind-list-of-images-using-knockout-in-page-with-loading-spinner

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!