击倒渲染完成后如何引发事件?

时间:2014-04-11 13:11:10

标签: jquery-mobile knockout.js

这个jquery移动表正在使用淘汰赛进行渲染。

<table data-role="table" id="report-table" class="ui-body-a ui-shadow ui-responsive table-stripe"
    data-column-btn-theme="a" data-column-btn-text="Spalten..." data-column-popup-theme="a" data-mode="columntoggle"">
    <thead>
        <tr data-bind="foreach: columns">
            <th data-bind="text: $data.Caption, attr: { 'data-priority': 1 + Math.floor($index() / 4) }"></th>
        </tr>
    </thead>
    <tbody data-bind="foreach: { data: rows, afterRender: tableRowAfterRender }">
        <tr data-bind="foreach: $parent.columns">
            <!-- ko template: { name: $data.template } -->
            <!-- /ko -->
        </tr>
    </tbody>
</table>

获得&#34; columntoggle&#34;实际工作,我目前使用&#34; aferRender&#34;事件:

self.tableRowAfterRender = function (element, data) {
    // Skip unless data.Items()[i] is not the last element in the rows collections
    for (var i = 0; i < data.Items().length - 1; i++) {
        if (data.Items()[i] !== self.rows()[self.rows().length - 1].Items()[i])
            return;
    }

    // refresh table after 100ms delay
    setTimeout(function () { $("#report-table").table("refresh"); }, 100);
}

这是不稳定的,我讨厌setTimeout()做事的方式,这种情况变得安静,我用jquery mobile和knockout。我需要一种强大的方法来提升一个事件,一旦所有的淘汰渲染,或理想情况下,一旦所有渲染涉及table-element内的元素完成。我能够在某些情况下使用自定义绑定,但我不知道如何在这里执行此操作。

3 个答案:

答案 0 :(得分:2)

试试这个。用:<div data-bind='template: { afterRender: myPostProcessingLogic }'>.换行表然后在myPostProsssingLogic中执行您需要做的任何事情。这只会在首次呈现表时调用。这是fiddle

 <div data-bind='template: { afterRender: myPostProcessingLogic }'> 
<table data-role="table" id="report-table" class="ui-body-a ui-shadow ui-responsive table-stripe"
    data-column-btn-theme="a" data-column-btn-text="Spalten..." data-column-popup-theme="a" data-mode="columntoggle"">
    <thead>
        <tr data-bind="foreach: columns">
            <th data-bind="text: $data.Caption, attr: { 'data-priority': 1 + Math.floor($index() / 4) }"></th>
        </tr>
    </thead>
    <tbody data-bind="foreach: { data: rows, afterRender: tableRowAfterRender }">
        <tr data-bind="foreach: $parent.columns">
            <!-- ko template: { name: $data.template } -->
            <!-- /ko -->
        </tr>
    </tbody>
</table>

答案 1 :(得分:1)

您可以尝试使用绑定 init

ko.bindingHandlers.init = {
    init: function(element, valueAccessor, allBindings, viewModel) {
        var action = valueAccessor();
        if (typeof action === 'function') {
            setTimeout(action.bind(viewModel, element), 0);
        }
    }
};

像这样:

ko.components.register('simple-component', {
    viewModel: function(params) {        
        this.title = params.title;
        this.initHandler = function() {
            console.log('DOM of component has been built.');
        };
    },
    template:
        '<div data-bind="init: initHandler">\
            Title is: <span data-bind="text: title"></span>\
        </div>'
});

更复杂案例的信息在这里 - http://blog.atott.ru/2015/08/dom-built-event-for-knockout-components.html

答案 2 :(得分:0)

有一种简单的方法。这是过程

为您的行分配一个类

<tr class="row" data-bind="foreach: $parent.columns">

使用条件

检入您的功能
if(data.Items().length == $('row').length){
    $("#report-table").table("refresh")
}

或手动调用任何事件

$('#report-table').trigger('click')

希望这对你有所帮助。

编辑:

创建一个新的observable并将其设置为false。

self.EnableTimeOut = ko.observable(false)

现在根据您的要求设置为true。这只是一个例子

if(data.Items().length == $('row').length && data.Items().length > 0){
    self.EnableTimeOut(true)
    $("#report-table").table("refresh")
}

最后

将其包裹在条件

setTimeout(function () { 
    if(self.EnableTimeOut()){
        $("#report-table").table("refresh"); 
    }
}, 100);