渲染后的淘汰赛过早触发

Knockout afterRender fires too early

本文关键字:淘汰赛      更新时间:2023-09-26

我指定了一些knockout绑定。我需要运行一些脚本后,整个页面被渲染。

<div class="row-fluid" data-bind="foreach: { data: rows, afterRender: myCallback }">
</div>

不幸的是,myCallback被调用得太早-并不是所有的DOM元素都被渲染,元素的大小还没有计算(更重要的是,myCallback需要调用init函数的堵塞,这需要计算所有元素的大小)

我怎么能调用myCallback时,页面上的所有DOM元素被渲染(和绑定应用)?

我写了一个小hack:

<div class="location-map-div" data-bind="openLayers: Value, attr: { style: 'width: 50%; height: 200px' }" style="width:100px; height:100px"></div>

我已经设置了内联样式,所以我的插件可以初始化,然后改变大小与knockout绑定

afterRender在你的'rows'数组中的每个元素被调用。你应该检查你是否在最后一个元素上。

<div class="row-fluid" data-bind="foreach: { data: rows, afterRender: thenDoStuff }">
</div>
viewModel.lastItem = ko.computed(function() {
    return this.items()[this.items().length - 1];
}, viewModel);
viewModel.thenDoStuff = function(elements, data) {
    if (data === viewModel.lastItem()) {
        alert('last one!');
        var parent = $(elements).filter('li').parent();
    }
};

下面是我发现并修改的一个例子:http://jsfiddle.net/Z6yqq/8/

您可以创建一个自定义绑定,在呈现过程中调用事件:

ko.bindingHandlers.onRender = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var value = valueAccessor();
        var events = ko.unwrap(value);
       if(events.once)
           events.once.call();
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var value = valueAccessor();
        var events = ko.unwrap(value);
       if(typeof events == 'function')
          events.call();
        if(events.each)
           events.each.call();
    } 
};

绑定的使用方法如下:

<div data-bind="onRender:{once: firstCall, each: eachCall}"/> 

每次knockout渲染这个div时,都会调用eachCall函数。

看到小提琴