【问题标题】:DataTables Pipelining and FixedColumns数据表流水线和固定列
【发布时间】:2014-01-24 07:53:44
【问题描述】:

我目前有一个使用流水线的 DataTable,我现在还需要它来使用 FixedColumns。我可以在浏览器控制台中完成,但加载后自动运行,我不知所措。

我在 fnInitComplete 中有什么:

var someObj = new FixedColumns(oTable, {
                                    "iLeftColumns": 6,
                                    "iLeftWidth": 600
                                  });

虽然这似乎重新加载了表格或其他东西,因为 fnDrawCallback 和 fnRowCallback 在此之后被调用了很多次。

编辑: 这是我能找到的最接近的示例,但是它不使用流水线。 http://datatables.net/release-datatables/extras/FixedColumns/server-side-processing.html

【问题讨论】:

  • 不确定您的问题是什么。让我们看一下我为您构建的一个基本工作示例。

标签: javascript jquery datatables jquery-datatables


【解决方案1】:

我已经将简单的工作示例放在一起。将 FixedColumns 初始化代码放入 fnInitComplete 就足够了:

var oTable = $('#example').dataTable( {
    // ...
    ,"sScrollX": "100%"
    ,"sScrollXInner": "150%"
    ,"fnInitComplete": function () {
        var someObj = new FixedColumns(oTable, {
                    "iLeftColumns": 1,
                    "iLeftWidth": 50
        });
    }
} );

我使用pipe-lining example from datatables 构建了一个示例并添加了 FixedColumns 代码。我参考了他们的服务器端 PHP 脚本,并通过PHP GET proxy 解决了 XSS 问题。完整的测试示例代码在这里(您可以将其粘贴到您自己的文件中):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <!--<base href="http://datatables.net/examples/server_side/"> -->
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" type="image/ico" href="http://www.sprymedia.co.uk/media/images/favicon.ico" />

        <title>DataTables example</title>
        <style type="text/css" title="currentStyle">
            @import "http://datatables.net/release-datatables/media/css/demo_page.css";
            @import "http://datatables.net/release-datatables/media/css/demo_table.css";
        </style>
        <script type="text/javascript" language="javascript" src="http://datatables.net/release-datatables/media/js/jquery.js"></script>
        <script type="text/javascript" language="javascript" src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js"></script>
        <script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/extras/FixedColumns/media/js/FixedColumns.js"></script>
        <script type="text/javascript" charset="utf-8">


var oCache = {
    iCacheLower: -1
};

function fnSetKey( aoData, sKey, mValue )
{
    for ( var i=0, iLen=aoData.length ; i<iLen ; i++ )
    {
        if ( aoData[i].name == sKey )
        {
            aoData[i].value = mValue;
        }
    }
}

function fnGetKey( aoData, sKey )
{
    for ( var i=0, iLen=aoData.length ; i<iLen ; i++ )
    {
        if ( aoData[i].name == sKey )
        {
            return aoData[i].value;
        }
    }
    return null;
}

var hadSomeData = false;

function fnDataTablesPipeline ( sSource, aoData, fnCallback ) {
    var iPipe = 5; /* Ajust the pipe size */

    var bNeedServer = false;
    var sEcho = fnGetKey(aoData, "sEcho");
    var iRequestStart = fnGetKey(aoData, "iDisplayStart");
    var iRequestLength = fnGetKey(aoData, "iDisplayLength");
    var iRequestEnd = iRequestStart + iRequestLength;
    oCache.iDisplayStart = iRequestStart;

    console.log('pipeline called');
    /* outside pipeline? */
    if ( oCache.iCacheLower < 0 || iRequestStart < oCache.iCacheLower || iRequestEnd > oCache.iCacheUpper )
    {
        bNeedServer = true;
    }

    /* sorting etc changed? */
    if ( oCache.lastRequest && !bNeedServer )
    {
        for( var i=0, iLen=aoData.length ; i<iLen ; i++ )
        {
            if ( aoData[i].name != "iDisplayStart" && aoData[i].name != "iDisplayLength" && aoData[i].name != "sEcho" )
            {
                if ( aoData[i].value != oCache.lastRequest[i].value )
                {
                    bNeedServer = true;
                    break;
                }
            }
        }
    }

    /* Store the request for checking next time around */
    oCache.lastRequest = aoData.slice();

    if ( bNeedServer )
    {
        if ( iRequestStart < oCache.iCacheLower )
        {
            iRequestStart = iRequestStart - (iRequestLength*(iPipe-1));
            if ( iRequestStart < 0 )
            {
                iRequestStart = 0;
            }
        }

        oCache.iCacheLower = iRequestStart;
        oCache.iCacheUpper = iRequestStart + (iRequestLength * iPipe);
        oCache.iDisplayLength = fnGetKey( aoData, "iDisplayLength" );
        fnSetKey( aoData, "iDisplayStart", iRequestStart );
        fnSetKey( aoData, "iDisplayLength", iRequestLength*iPipe );
        console.log('actually asking server!');

        $.getJSON( sSource, aoData, function (json) { 
            /* Callback processing */
            console.log('got back!');
            oCache.lastJson = jQuery.extend(true, {}, json);

            if ( oCache.iCacheLower != oCache.iDisplayStart )
            {
                json.aaData.splice( 0, oCache.iDisplayStart-oCache.iCacheLower );
            }
            json.aaData.splice( oCache.iDisplayLength, json.aaData.length );

            console.log('have data 2! ' + json.aaData.length);
            hadSomeData = true;
            fnCallback(json);
            console.log('after callback');
        } );
    }
    else
    {
        json = jQuery.extend(true, {}, oCache.lastJson);
        json.sEcho = sEcho; /* Update the echo for each response */
        console.log('have data! ' + json.aaData.length);
        json.aaData.splice( 0, iRequestStart-oCache.iCacheLower );
        json.aaData.splice( iRequestLength, json.aaData.length );
        hadSomeData = true;
        fnCallback(json);
        return;
    }

}

$(document).ready(function() {

var fixedColDone = false;

    var oTable = $('#example').dataTable( {
        "bProcessing": true,
        "bServerSide": true,
//      "sAjaxSource": "http://datatables.net/examples/examples_support/server_processing.php",
        "sAjaxSource": "get_proxy.php",
        "fnServerData": fnDataTablesPipeline
        ,"sScrollX": "100%"
        ,"sScrollXInner": "150%"
/*  ,"fnDrawCallback": function () {
        console.log('draw callback');
        if (!fixedColDone && hadSomeData) {
            console.log('actually drawing!');
            var someObj = new FixedColumns(oTable, {
                                    "iLeftColumns": 1,
                                    "iLeftWidth": 50
                                  });       
            fixedColDone = true;
        }
    }*/
    ,"fnInitComplete": function () {
            var someObj = new FixedColumns(oTable, {
                                    "iLeftColumns": 1,
                                    "iLeftWidth": 50
                                  });       
    }
    } );


/*setTimeout(function () {
}, 5000);*/

} );
</script>
    </head>
    <body id="dt_example">
        <div id="container">
            <div class="full_width big">
                <i>DataTables</i> server-side processing with pipelining example
            </div>

            <h1>Preamble</h1>
            <p>When using server-side processing with DataTables, it can be quite intensive on your server having an Ajax call every time the user performs some kind of interaction - you can effectively DDOS your server with your own application!</p>
            <p>This example shows how you might over-come this by modifying the request set to the server to retrieve more information than is actually required for a single page's display. This means that the user can page multiple times (5 times the display size is the default) before a request must be made of the server. Paging is typically the most common interaction performed with a DataTable, so this can be most beneficial to your server's resource usage. Of course the pipeline must be cleared for interactions other than paging (sorting, filtering etc), but that's the trade off that can be made (sending extra information is cheep - while another XHR is expensive).</p>

            <h1>Live example</h1>
            <div id="dynamic">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="example" style="width: 200px;">
    <thead>
        <tr>
            <th width="20%">Rendering engine</th>
            <th width="25%">Browser</th>
            <th width="25%">Platform(s)</th>
            <th width="15%">Engine version</th>
            <th width="15%">CSS grade</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td colspan="5" class="dataTables_empty">Loading data from server</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <th>Rendering engine</th>
            <th>Browser</th>
            <th>Platform(s)</th>
            <th>Engine version</th>
            <th>CSS grade</th>
        </tr>
    </tfoot>
</table>
</body>
</html>

还有来自https://stackoverflow.com/a/18800645/684229的get_proxy.php(必须保存到同一目录)

<?php

$url = 'http://datatables.net/examples/examples_support/server_processing.php'; //Edit your target here

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url . "?" . $_SERVER['QUERY_STRING']);

//execute post
$result = curl_exec($ch);

//close connection
curl_close($ch);

?>

编辑:尝试将初始化放在此处(从其他地方删除):

setTimeout(function () {
    var someObj = new FixedColumns(oTable, {
                "iLeftColumns": 1,
                "iLeftWidth": 50
    });
}, 10000);

然后等待 10 秒。现在显示正确了吗?

【讨论】:

  • 我在 fnInitComplete 中设置了 Fixed Columns 初始化,但之后它似乎调用了 fnRowCallback 大约 50 次
  • @Raymond 是的,但它为什么重要?
  • 我已经尝试过超时,它工作正常,但它不能作为最终解决方案。 (它也取消了我使用 fnRowCallback 进行的格式设置;我想我可以将格式移动到固定列之后)
  • @Raymond 好的。但是,如果您不提供代码,则很难为您提供帮助。我展示了一个有效的例子。您可能会做更多的事情来破坏功能,但是如果您不提供更多信息,就很难知道在哪里。发布我们可以玩的整个工作示例将是最好的。
  • 我看看我能做什么
猜你喜欢
  • 2011-10-03
  • 2017-11-29
  • 1970-01-01
  • 2022-07-14
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
  • 2019-09-21
相关资源
最近更新 更多