Javascript 使用KnockoutJS加载所有图像(并执行某些操作)后进行捕获

Javascript 使用KnockoutJS加载所有图像(并执行某些操作)后进行捕获,javascript,knockout.js,jquery-deferred,Javascript,Knockout.js,Jquery Deferred,我目前有一个基本的实现,可以在加载所有图像时捕获,但我对代码、可伸缩性以及UI和viewModel之间的紧密耦合感到不满意 我在viewModel和bindingHandler之外声明了一系列承诺,以便每个承诺都可以访问它。bindingHandler将把每个未解析的承诺推送到数组中,init函数将等待数组收到所有已解析的承诺。一旦发生这种情况,就会调用一个函数,为所有图像设置统一的高度 以下是用户界面: <ul data-bind="foreach: movies"> &l

我目前有一个基本的实现,可以在加载所有图像时捕获,但我对代码、可伸缩性以及UI和viewModel之间的紧密耦合感到不满意

我在viewModel和bindingHandler之外声明了一系列承诺,以便每个承诺都可以访问它。bindingHandler将把每个未解析的承诺推送到数组中,init函数将等待数组收到所有已解析的承诺。一旦发生这种情况,就会调用一个函数,为所有图像设置统一的高度

以下是用户界面:

<ul data-bind="foreach: movies">
    <li>
        <div class="image">
            <img data-bind="imageLoad: { src: posters.Detailed, alt: title }"/>
        </div>
    </li>
</ul>
在一个完美的世界中,我的viewModel只需将回调传递给我的bindingHandler,但它是动态的,它不需要了解任何有关UI的信息,bindingHandler将能够确定它需要调整的元素。我曾经玩弄过某种延迟可观察的想法,但最后我只是不高兴在viewModel中有这种想法。我还考虑过在父元素上使用
data-
属性来确定实际设置高度的元素,但这似乎有些草率

我觉得我错过了什么


那么,我要问的是,有什么更好的方法可以实现这一点,从而允许松散耦合和可伸缩性,这样我就不必从我的viewModel中明确告诉UI要做什么(尽可能多)以及什么时候做?

在处理它的foreach范围中使用自定义绑定。例如:

<ul data-bind="foreach: movies, uniformHeight: movies">
    <li>
        <div class="image">
            <img data-bind="imageLoad: { src: posters.Detailed, alt: title }"/>
        </div>
    </li>
</ul>
这可能需要围绕如何处理
robot.ko.models.Movie
中的逻辑进行更多的重组,但根据您发布的内容,没有什么大不了的

基于资源的方法 需要更多的管道,但最终可能会更可靠


您的外部
uniformHeight
绑定可以在
bindingContext
上注册自身,并等待子
imageLoad
绑定每次都会引发一个事件,以通知图像已加载;当它们回来时,累积高度,可能会去盎司。

为什么要进行向下投票,请解释我也考虑过在父元素上使用数据属性来知道实际设置高度的元素,但这似乎有些草率。为什么?我认为这是唯一正确的方法。你可以在绑定处理程序中访问你的整个VM,为什么你不能做一个完美的例子呢?如果您想实现松耦合,可以创建特定于域的处理程序。还有,为什么要等到所有图像都设置好高度后再开始呢?这些图像是从外部域加载的。它们需要不同的时间来加载。一旦它们全部加载,我需要为周围的父对象设置一个高度,使它们统一。我只是在css3中做这件事,这看起来很有希望。谢谢你,雷克斯。我现在工作很忙,所以可能需要一个星期左右的时间,我才能开始实施这个计划,并回答问题。
<ul data-bind="foreach: movies, uniformHeight: movies">
    <li>
        <div class="image">
            <img data-bind="imageLoad: { src: posters.Detailed, alt: title }"/>
        </div>
    </li>
</ul>
ko.bindingHandlers.uniformHeight = {
  init: function(element, valueAccessor) {
      //assume valueAccessor contains an array of promises
      $.when.apply($, valueAccessor()()).done(function () {
            robot.utils.setThumbnailHeight($(element).find('.thumbnails li'), function () {
                self.isLoading(false);
            });
      });
  }
};