问题
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