【发布时间】:2013-03-16 03:39:28
【问题描述】:
我目前有一个基本实现,可以捕获所有图像的加载时间,但我对代码、可伸缩性以及 UI 和 viewModel 之间的紧密耦合不满意。
我在 viewModel 和 bindingHandler 之外声明了一组 promise,以便每个都可以访问它。 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- 属性来了解实际设置高度的元素,但这似乎很草率。
我觉得我错过了什么。
所以,我在问,有什么更好的方法来实现这一点,允许松散耦合和可扩展性,这样我就不必专门告诉 UI(尽可能多地)做什么以及何时做,来自我的 viewModel?
【问题讨论】:
-
为什么投反对票,请解释一下
-
我也考虑过在父元素上使用 data- 属性来了解实际设置高度的元素,但这似乎很草率。 为什么?恕我直言,这是唯一正确的方法。
-
您可以在绑定处理程序中访问您的整个虚拟机,为什么不能做您的完美世界示例?如果要实现松耦合,可以制作特定于域的处理程序。还有,你为什么要等到所有图像都完成后才设置它们的高度?
-
图像正在从外部域加载。它们需要不同的时间来加载。一旦它们全部加载完毕,我需要为周围的父级设置一个高度,以便它们是统一的。我只是在 css3 中这样做。
标签: javascript knockout.js jquery-deferred