DataTables Pipelining和FixedColumns

时间:2014-01-06 19:45:27

标签: javascript jquery datatables jquery-datatables

我目前有一个使用流水线技术的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

1 个答案:

答案 0 :(得分:0)

我把简单的工作示例放在一起。将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>

get_proxy.php(您必须将其保存到同一目录中),派生自https://stackoverflow.com/a/18800645/684229

<?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秒钟。它现在显示正确吗?