【问题标题】:datatables - preload data to array via ajax performs multiple connectionsdatatables - 通过 ajax 将数据预加载到数组执行多个连接
【发布时间】:2015-06-05 12:37:11
【问题描述】:

按照this 教程,我最终得到了这段代码(基本上将子行内容从外部文件加载,用 JsRender 解析,到一个数组):

/* Formatting function for row details - modify as you need */
function format ( d ) {
    // `d` is the original data object for the row
    // carica il template del dettaglio
    $.ajax ({
        async: false,
        type: "POST",
        url: "incaricodetail.html",
        cache: false,
        success: function(data){
            templateHtml = data; 
        }
    });
    var template = $.templates(templateHtml);
    var htmlOutput = template.render(d);

    return htmlOutput;
}

$(document).ready(function() {

    $.fn.dataTable.moment( 'DD/MM/YYYY' ); 
    var dettagli = []; 
    var table = $('#tabellaDati').DataTable( {
        "data": <?= json_encode($stmt->fetchAll(PDO::FETCH_ASSOC));?>,  
        "columns": [
            {
                "className":      'details-control',
                "orderable":      false,
                "data":           null,
                "defaultContent":
                    '<a class="btn btn-xs" href="incarico_edit.php?id=<?=$id;?>&pageFrom=<?=pathinfo($_SERVER['PHP_SELF'], PATHINFO_FILENAME ); ?>" title="Modifica"><span class="glyphicon glyphicon-edit"></span></a>'+
                    '<a class="btn btn-xs delete-object" href="delete.php?id=<?=$row["id"]?>" delete-id="{$id}"" title="Elimina"><span class="glyphicon glyphicon-trash"></span></a>'+
                    '<a class="btn btn-xs" href="#" id="mostraDettaglio" title="dettaglio"><span class="glyphicon glyphicon-plus"></span></a>',
                    "render": function(data, type, row, meta) {
                        dettagli[meta.row] = format(data);
                    }

           },
           { "data": "id" },
           { "data": "protocollo" },
           { 
              "data": "dataIncarico",
              "type": "date",
              "dateFormat": "dd-mm-yyyy"
           }

        ],
        "order": [[1, 'asc']]
    });

    // Add event listener for opening and closing details
    $('#tabellaDati tbody #mostraDettaglio').on('click', function () {
        var tr = $(this).closest('tr');
        var row = table.row( tr );

        if ( row.child.isShown() ) {
            // This row is already open - close it
            row.child.hide();
            tr.removeClass('shown');
        }
        else {
            // Open this row
            row.child(dettagli[row.index()]).show();
            tr.addClass('shown');
        }
    } );
} );

我不知道为什么,但是对文件 incaricodetail.html 的 ajax 调用执行了 3 次(例如,对于两条记录,我得到了 6 个 POST 连接)。

DataTables 调试器代码:onucak

为什么会这样? 亚历克斯

【问题讨论】:

    标签: jquery datatables


    【解决方案1】:

    初始化时,render 会被多次调用:

    • 显示
    • 排序
    • 过滤器
    • 类型(检测)

    这是每一行!您可以通过type 参数检查渲染调用的类型。一个合格的猜测是你的渲染函数在typedisplayfilter上被调用——你有2行,它对format()函数进行了6次调用,并且由于你已经打开了@ 987654327@关闭。

    您可以通过简单的方式避免这种情况:

    render: function(data, type, row, meta) {
       if (typeof dettagli[meta.row] == 'undefined') {
          dettagli[meta.row] = format(data);
       }
    }
    

    为什么使用不同的type 多次调用渲染?
    因此,您可以为不同的目的返回不同的数据。假设您有一些包含复选框作为显示的 HTML,对于排序,您可以传递 0,对于过滤,您可以传递是/否,对于类型,您可以传递数字。


    更新。在 initComplete() 中初始化 dettagli[] 而不是 render()

    var table = $('#example').DataTable({
        initComplete : function() {
            var api = this.api(),
                rowCount = api.data().length;
            for (var i=0;i<rowCount;i++) {
                dettagli[i] = format(api.row(i).data()[0]);
            }    
        }        
    });
    

    这应该与dettagli[meta.row] = format(data); 做同样的事情,即调用format() 并为每一行提供第0 列的内容。

    您还应该考虑只加载一次incaricodetail.html。为什么每次都一遍又一遍地加载它? incaricodetail.html 的内容似乎并没有改变,所以会改变

    var template;
    $.get("incaricodetail.html", function(html) {
       template = $.templates(html);
    });
    
    function format ( d ) {
       return template.render(d);
    }
    

    不完全一样?

    【讨论】:

    • 它有效,谢谢。现在我有另一个问题(使用分页时再次从磁盘获取数据)但我会单独发布。
    • @alzambo,你为什么不做 initComplete 的东西呢?一直认为使用渲染对您来说有点奇怪,您可以删除新问题,我很乐意更新这个答案。只需initComplete : function (for var i=0; .... { dettagli[meta.row] = format(data); }}
    • 我试过了:"initComplete": function( settings, json ) { for (i=0; i dettagli 或 meta
    • 好的,我想我得到了一些东西:有了这个循环for (i=0; i &lt; this.api().data().length; i++) {data = this.api().row(i).data();dettagli[i] = format(data);},我有正确的连接,但是当打开子行时,比如说,第二页,它会从文件重新加载
    • @alzambo,请参阅更新。今晚还有其他紧急事情要做。
    猜你喜欢
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 2014-12-03
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多