我目前有一个基本实现,可以捕获所有图像何时加载,但我对代码、可伸缩性以及 UI 和 viewModel 之间的紧密耦合不满意。
我在 viewModel 和 bindingHandler 之外声明了一系列承诺,以便每个人都可以访问它。bindingHandler 会将每个未解析的 promise 推送到数组中,并且 init 函数将等待数组接收到所有已解析的 promise。一旦发生这种情况,就会调用一个为所有图像设置统一高度的函数。
这是用户界面:
<ul data-bind="foreach: movies">
<li>
<div class="image">
<img data-bind="imageLoad: { src: posters.Detailed, alt: title }"/>
</div>
</li>
</ul>
另一边:
function ViewModel() {
var self = this;
self.movies = ko.observableArray([]);
self.init = function(data) {
self.isLoading(true);
self.movies = ko.utils.arrayMap(data, function(item) {
return new robot.ko.models.Movie(item);
});
$.when.apply($, promises).done(function () {
robot.utils.setThumbnailHeight($('.thumbnails li'), function () {
self.isLoading(false);
});
});
};
}
ko.bindingHandlers.imageLoad = {
init: function(element, valueAccessor) {
var options = valueAccessor() || {};
var promise = $.Deferred();
var loadHandler = function() { return promise.resolve; };
promises.push(promise);
ko.applyBindingsToNode(element, {
event: { load: loadHandler },
attr: { src: options.src, alt: options.alt }
});
}
}
在一个完美的世界中,我的 viewModel 只会将回调传递给我的 bindingHandler,但它会是动态的,它不需要了解有关 UI 的任何信息,并且 bindingHandler 将能够确定它需要调整哪个元素。我玩弄了某种 deferredObservable 的想法,但最后我只是不高兴在 viewModel 中有这个。我还考虑过data-
在父元素上使用属性来知道实际设置高度的元素,但这似乎很草率。
我觉得我错过了什么。
所以,我在问,有什么更好的方法来实现这一点,它允许松散耦合和可伸缩性,这样我就不必从我的 viewModel 中专门告诉 UI 做什么(尽可能多地)以及何时做什么?