简体   繁体   English

如何使用 DataTables 其他页面更新实时数据

[英]How to Update live data with DataTables other pages

There is no problem updating the current page(websocket).更新当前页面(websocket)没有问题。
However, other pages are not updated, so filter is not working properly.但是,其他页面没有更新,因此过滤器无法正常工作。


further explanation进一步解释
There's about 2,000 data, updated in real time.大约有 2,000 个数据,实时更新。 If all 2000 data are displayed on one page without pagiation, all data is updated without any problems, and the ordering filter is also refreshed every 10 seconds with no problem.如果2000条数据全部显示在一页上,没有分页,所有数据都更新没有问题,排序过滤器也每10秒刷新一次也没有问题。 The problem is that when pagination is performed, for example, when displaying 100 data per page, Only 100 data is updated and the rest of the data is not updated.问题是在进行分页时,例如每页显示100条数据时,只更新了100条数据,而数据的rest没有更新。 As a result, the ordering filter is not working properly.结果,排序过滤器无法正常工作。


-- js code --js代码
It is refreshed every 10 seconds(setInterval)每 10 秒刷新一次(setInterval)
Customized for numerical sorting.(dom-text-numeric)为数字排序定制。(dom-text-numeric)

/* Create an array with the values of all the input boxes in a column, parsed as numbers */
$.fn.dataTable.ext.order['dom-text-numeric'] = function (settings, col) {
    return this.api()
        .column(col, {order: 'index'})
        .nodes()
        .map(function (td, i) {
            return $(td).text() * 1;
        });
};


/* Initialise the table with the required column ordering data types */
$(document).ready(function () {
    var myTable = $('#example').DataTable({
        responsive: true,
        //paging: false,
        pageLength:100,
        columns: [
            null,
            {orderDataType: 'dom-text-numeric'},
            {orderDataType: 'dom-text-numeric'},
            {orderDataType: 'dom-text-numeric'},
        ],
        order: [[1, 'desc']],

    });
    setInterval(function () {
        myTable.rows().invalidate().draw();
    }, 10000);


});

html--This is some rendered data. html——这是一些渲染的数据。

 <table id="example" class="table table-striped table-bordered dt-responsive nowrap w-100 dataTable no-footer" style="width: 100%;" aria-describedby="example_info">
  <thead>
    <tr>
      <th class="sorting" tabindex="0" aria-controls="example" rowspan="1" colspan="1" aria-label="Name: activate to sort column ascending" style="width: 442px;">Name</th>
      <th class="sorting sorting_desc" tabindex="0" aria-controls="example" rowspan="1" colspan="1" aria-label="premium: activate to sort column ascending" style="width: 282px;" aria-sort="descending">premium</th>
      <th class="sorting" tabindex="0" aria-controls="example" rowspan="1" colspan="1" aria-label="binance: activate to sort column ascending" style="width: 292px;">binance</th>
      <th class="sorting" tabindex="0" aria-controls="example" rowspan="1" colspan="1" aria-label="upbit: activate to sort column ascending" style="width: 346px;">upbit</th>
    </tr>
  </thead>
  <tbody>
    <tr class="odd">
      <td class="name_DNT-BTC">DNT-BTC</td>
      <td class="premium_DNT-BTC sorting_1">1.0087</td>
      <td class="binanceSpot_DNTBTC" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00000233</td>
      <td class="upbitSpot_BTC-DNT" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00000231</td>
    </tr>
    <tr class="even">
      <td class="name_SNT-BTC">SNT-BTC</td>
      <td class="premium_SNT-BTC sorting_1">1.0072</td>
      <td class="binanceSpot_SNTBTC" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00000138</td>
      <td class="upbitSpot_BTC-SNT" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">-</td>
    </tr>
    <tr class="odd">
      <td class="name_TRX-BTC">TRX-BTC</td>
      <td class="premium_TRX-BTC sorting_1">1.0067</td>
      <td class="binanceSpot_TRXBTC" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00000299</td>
      <td class="upbitSpot_BTC-TRX" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">-</td>
    </tr>
    <tr class="even">
      <td class="name_ETH-USDT">ETH-USDT</td>
      <td class="premium_ETH-USDT sorting_1">1.0053</td>
      <td class="binanceSpot_ETHUSDT" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">1681.08</td>
      <td class="upbitSpot_USDT-ETH" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">1672.2989054</td>
    </tr>
    <tr class="odd">
      <td class="name_ETH-BTC">ETH-BTC</td>
      <td class="premium_ETH-BTC sorting_1">1.0050</td>
      <td class="binanceSpot_ETHBTC" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.073392</td>
      <td class="upbitSpot_BTC-ETH" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">-</td>
    </tr>
    <tr class="even">
      <td class="name_LINK-BTC">LINK-BTC</td>
      <td class="premium_LINK-BTC sorting_1">1.0047</td>
      <td class="binanceSpot_LINKBTC" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.0003658</td>
      <td class="upbitSpot_BTC-LINK" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00036409</td>
    </tr>
    <tr class="odd">
      <td class="name_LRC-BTC">LRC-BTC</td>
      <td class="premium_LRC-BTC sorting_1">1.0047</td>
      <td class="binanceSpot_LRCBTC" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00001917</td>
      <td class="upbitSpot_BTC-LRC" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">-</td>
    </tr>
    <tr class="even">
      <td class="name_BNT-BTC">BNT-BTC</td>
      <td class="premium_BNT-BTC sorting_1">1.0040</td>
      <td class="binanceSpot_BNTBTC" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00002527</td>
      <td class="upbitSpot_BTC-BNT" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00002537</td>
    </tr>
    <tr class="odd">
      <td class="name_EOS-BTC">EOS-BTC</td>
      <td class="premium_EOS-BTC sorting_1">1.0025</td>
      <td class="binanceSpot_EOSBTC" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.0000513</td>
      <td class="upbitSpot_BTC-EOS" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00005143</td>
    </tr>
    <tr class="even">
      <td class="name_XRP-BTC">XRP-BTC</td>
      <td class="premium_XRP-BTC sorting_1">1.0025</td>
      <td class="binanceSpot_XRPBTC" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00001574</td>
      <td class="upbitSpot_BTC-XRP" data-bs-toggle="modal" data-bs-target="#bookModal" onclick="setOrderbookPair(this.className)">0.00001578</td>
    </tr>
  </tbody>
</table>

--js -socket --js -socket
Receives real-time data from the Beckend Consumer (via on-message.)从 Beckend 消费者接收实时数据(通过消息。)

 function auto_reconnect_ticker_socket() {
    let ws = new WebSocket(
        'ws://' + window.location.host +
        '/ws/ticker?session_key=${sessionKey}')
    ws.onopen = function () {
        // subscribe to some channels
        ws.send(JSON.stringify({
            //.... some message the I must send when I connect ....
        }));
    };

    ws.onmessage = function (e) {
        let data = JSON.parse(e.data);
        let site = data['site'];
        let type = data['type'];

        if (type == 'ticker') {
            data['data'].forEach((c, i, a) => {
                document.querySelector(`.${site}_${c.symbol}`) && update_price(site, c.symbol, c.price_trade)
                document.querySelector(`.${site}_${c.symbol}`) && update_premium(c.name, c.premium)
                //&& update_price_change_24h(site, c.s, c.o, c.c)
            });
        }


    }

    ws.onclose = function (e) {
        console.log('Ticker Socket is closed. Reconnect will be attempted in 1 second.', e.reason);
        setTimeout(function () {
            auto_reconnect_ticker_socket();
        }, 1000);
    };

    ws.onerror = function (err) {
        auto_reconnect_ticker_socket.error('Socket encountered error: ', err.message, 'Closing socket');
        ws.close();
    };
    return ws
}

Is there a way to update other pages with the DataTables?有没有办法用 DataTables 更新其他页面?

Your code is currently updating data in the DOM using query selectors such as:您的代码当前正在使用查询选择器更新 DOM 中的数据,例如:

document.querySelector(`.${site}_${c.symbol}`) && update_price(site, c.symbol, c.price_trade)

This will only update the HTML for data on the currently visible page (as you have noted).这只会更新 HTML 以获取当前可见页面上的数据(如您所述)。 DataTables will not know anything about these changes. DataTables 对这些更改一无所知。

Instead you need to use the DataTables API when performing your data updates.相反,在执行数据更新时,您需要使用 DataTables API。

One way to do this is to use a column containing a unique identifier - which in your case appears to be column 1 (index 0) - the "Name" column.一种方法是使用包含唯一标识符的列 - 在您的情况下,它似乎是第 1 列(索引 0) - “名称”列。

To update existing records in the table, I would use the following approach.要更新表中的现有记录,我将使用以下方法。

This assumes you get one name per socket event e .这假设您为每个套接字事件e获得一个名称。 If you get an array of names, then you would adjust to loop through each one, and only perform one draw() at the end:如果您得到一组名称,那么您将调整为循环遍历每个名称,最后只执行一次draw()

function updateTable(e) {
  let pairData = JSON.parse(e.data);        
  // check if "name" already exists in table:
  var index = table.column( 0, {order:'index'} ).data()
    .indexOf( pairData.name);        
  if (index >= 0) {
    // update the existing row:
    table.row( index, {order:'index'} ).data( pairData ).draw();
  } else {
    // insert a new row:
    table.row.add( pairData ).draw();
  }
}

You will need to adjust the above for your specific JSON contents.您需要针对您的特定 JSON 内容调整上述内容。 I use data for the contents of a row, and name for the unique identifier in each row.我将data用于一行的内容,并将name用于每行中的唯一标识符。

indexOf() - searches in column zero and locates the row index containing the unique name (eg DNT-BTC ). indexOf() - 在第 0 列中搜索并定位包含唯一name的行索引(例如DNT-BTC )。 It uses {order:'index'} to ensure the value returned represents the internally assigned index number used by DataTables (based on the initial data load order), not an index number dependent on filtering and/or sorting.它使用{order:'index'}来确保返回的值代表 DataTables 使用的内部分配的索引号(基于初始数据加载顺序),而不是依赖于过滤和/或排序的索引号。

row().data( newdata ) - retrieves the row of data for the previously found index number. row().data( newdata ) - 检索先前找到的索引号的数据行。 Updates the data for that row.更新该行的数据。 Re-draws the table.重新绘制表格。

Note that newdata can be an array or an object - depending on how the original row of data was created in DataTables.请注意, newdata可以是数组或 object - 取决于如何在 DataTables 中创建原始数据行。 In my code, I assume an object (the JSON message).在我的代码中,我假设一个 object(JSON 消息)。 In your question, you show the original data as being provided directly from the initial HTML - so that would be an array of data, not an object:在您的问题中,您将原始数据显示为直接从初始 HTML 提供 - 所以这将是一个数据数组,而不是 object:

[ 'DNT-BTC', 1.0087, 0.00000233, 0.00000231 ]

Finally, my code also inserts a new record, if its key value was not found anywhere in the DataTable.最后,如果在 DataTable 中的任何位置都找不到它的键值,我的代码还会插入一条新记录。 You may not need that, in your case.在你的情况下,你可能不需要那个。


The benefit of this approach is that it operates on the underlying DataTable via its API, and not on the DOM, which may only display part of that underlying data.这种方法的好处是它通过其 API 对基础 DataTable 进行操作,而不是在 DOM 上操作,DOM 可能只显示部分基础数据。 Also, if you only change values in the DOM, then any draw() call will cause that data to be lost (because such DOM changes do not exist in the underlying DataTables data).此外,如果您只更改 DOM 中的值,那么任何draw()调用都会导致该数据丢失(因为此类 DOM 更改不存在于底层 DataTables 数据中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM