2

我正在尝试创建一个自定义绑定,该绑定将在加载内容时显示加载 gif。

ko.bindingHandlers.loader = {
    init: function (element) {
        $('<div>').addClass('loader').hide().appendTo($(element));
    },
    update: function (element, valueAccessor) {
        var isLoading = ko.utils.unwrapObservable(valueAccessor());
        var $element = $(element);
        var $children = $element.children(':not(.loader)');
        var $loader = $(element).find('.loader');

        if(isLoading) {
            $children.stop(true).css('visibility', 'hidden').attr('disabled', 'disabled');
            $loader.stop().fadeIn();
        } else {
            $loader.stop(true).fadeOut(function () {
                $children.css('visibility', 'visible').removeAttr('disabled');
            });
        }
    }
};

我可以在div.loader附加到的 init 中看到,并且可以看到更新函数在更改为 trueelement时触发。isLoading但是一旦图像加载(通过加载我的意思是每个图像在其各自的加载事件上返回一个已解决的承诺)我看不到更新触发一次isLoading被设置回false。

视图模型

function viewModel() {
    var self = this;

    self.movies = ko.observableArray([]);
    self.searchValue = ko.observable();
    self.isLoading = ko.observable(false);

    self.search = function () {
        self.isLoading = true;
        $.getJSON(arguments[0].action, { name: this.searchValue() }, function (data) {
            self.movies(data);
            $.when.apply($, promises).done(function() {
                setThumbnailHeight(function () {
                    self.isLoading = false;
                });
            });
        });
    }; 
    var setThumbnailHeight = function(callback) {
        var $items = $('.thumbnails li');
        var maxHeight = Math.max.apply(null, $items.map(function () {
            return $(this).innerHeight();
        }).get());
        $items.css('height', maxHeight);
        callback();
    };

}

ko.applyBindings(new viewModel());

setThumbnailHeight正在正确的时间被调用(一旦所有的承诺都解决了)并且工作正常,因为我看到它将每个的高度设置为li最大高度并且可以看到回调(在这种情况下function(){ self.isLoading = false; } 被调用。

我的绑定

<ul class="content thumbnails" data-bind="foreach: movies, loader: $root.isLoading">
    <li class="movie">
        ...
    </li>
</ul>

回顾一下,问题在于加载 gif 将在isLoading设置为 true 时显示,但在设置回 false 时不会隐藏和显示新加载的内容。

4

1 回答 1

4

所有的 observables 都是函数,所以你不能使用=. 使用self.isLoading(true);代替self.isLoading = true;

self.search = function () {
    self.isLoading(true);
    $.getJSON(arguments[0].action, { name: this.searchValue() }, function (data) {
        self.movies(data);
        $.when.apply($, promises).done(function() {
            setThumbnailHeight(function () {
                self.isLoading(false);
            });
        });
    });
};

function(){ self.isLoading(false); }
于 2012-11-22T15:45:27.267 回答