Knockoutjs事件绑定到图像加载事件

时间:2012-11-20 12:05:29

标签: javascript event-handling knockout.js jquery-deferred

我正在使用Knockout.js显示从我的服务器返回的搜索结果列表。结果集中的每个结果都包含一个图像。我正在尝试将处理程序附加到每个图像的加载事件,因此我可以根据所有图像的最大高度调整图像的父div,但加载事件似乎是在图像加载完成之前触发。

此外,我可以看到加载处理程序在firebug中命中,但调试操作只是让图像有时间加载,所以在调试时一切正常。

我的viewModel中的加载处理程序:这会将已解析的延迟推送到我的promises数组中。然后,我所要做的就是检查以确保阵列已满,这将告诉我图像已加载。

self.imageLoadHandler = function() {
    var promise = $.Deferred().resolve;
    promises.push(promise);
};

装载处理程序的绑定

<img data-bind="attr: { src: Posters.Detailed, alt: Title }, event: { load: $root.imageLoadHandler }" />

我的viewModel中的搜索功能:这将返回json结果,填充我的observable数组,然后通过首先检查以确保promises数组已满来设置每个“thumbnail”的高度,然后如果是,获取最大高度并将所有“缩略图”设置为该高度。

self.search = function () {
    $.getJSON(arguments[0].action, { name: this.searchValue() }, function (data) {
        self.movies(data);
        setThumbnailHeight();
    });
};

var setThumbnailHeight = function() {
    var $items = $('.thumbnails li');
    $.when.apply($, promises).done(function() {
        var maxHeight = Math.max.apply(null, $items.map(function () {
            return $(this).height();
        }).get());
        $items.css('height', maxHeight);
    });
};

我的问题是:为什么在图像加载之前触发加载事件以及如何在适当的时间触发加载事件?

更新

我的想法是,加载事件可能会过早触发,因为它可能在图像有src之后附加。如果只是改变事件绑定的顺序不起作用,我可能必须创建一个自定义绑定。

1 个答案:

答案 0 :(得分:5)

您可以通过将event:数据放在attr:数据之前来解决事件绑定问题。

无论如何(没有双关语)这一行是错误的:

var promise = $.Deferred().resolve;

它创建一个延迟,然后将promise指定为resolve函数的引用,而不调用它。

当结果数组传递给$.when时,会立即解决组合的承诺,因为隐式地认为已经解析了本身不实现promise接口的对象。

您需要在imageLoadHandler之外创建延迟对象数组(所需长度),然后在该点显式调用适当的延迟对象上的.resolve()