DataTables:如何在preInit中设置页面?

时间:2016-12-11 06:00:52

标签: datatables

The docs说我应该可以通过DataTablesApiInstance.page(pageNumber)设置页面,但我无法让它工作。

所有其他API方法(如searchorder)似乎都能正常运行。

这是我的代码:

$(document)
    .on('preInit.dt', (ev, settings) => {
        let tableId = ev.target.id;
        let tableState = _.get(['datatables', tableId], history.state) || {};

        let api = new $.fn.dataTable.Api(settings);

        if(tableState.hasOwnProperty('page')) {
            api.page(tableState.page); // <-- problem is here; page doesn't get set
        }

        if(tableState.hasOwnProperty('search')) {
            api.search(tableState.search);
        }

        if(tableState.hasOwnProperty('order')) {
            api.order(tableState.order);
        }

        const setState = (key, value) => {
            history.replaceState(_.set(['datatables', tableId, key], value, history.state), '');
        };

        api.on('page', ev => {
            let info = api.page.info();
            // console.log('page', tableId, info.page);
            setState('page', info.page);
        });

        api.on('order', ev => {
            let order = api.order();
            // console.log('order', tableId, order);
            setState('order', order);
        });

        api.on('search', ev => {
            setState('search', api.search());
        });
    });

该方法已被点击,但未设置该页面。我使用错误的API方法吗?在数据加载之前是否有另一种设置页面的方法?

我正在使用datatables.net@1.10.12

如果我将呼叫推迟到init而不是preInit,则会突出显示正确的页码,但数据仍然来自第一页。如果我在其上添加0ms延迟(如下所示),它确实有效,但会导致第二次数据获取+绘制。

if(tableState.page) {
    api.on('init', ev => {
        setTimeout(() => {
            api.page(tableState.page).draw('page');
        }, 0);

    });
}

如何在不产生第二个ajax请求的情况下设置页面?

2 个答案:

答案 0 :(得分:2)

当使用分页为jQuery DataTables的displayStart的DataTables时,您可以使用recommended by the author选项来定义数据显示的起点。

它在服务器端处理模式下与表一起正常工作,只执行了1个Ajax请求。

var table = $("#example").DataTable({
     "processing": true,
     "serverSide": true,
     "ajax": "/test",
     "displayStart": 200     
 });

来自documentation

  

请注意,此参数是记录数(从0开始计算),而不是页码,因此,如果每页有10条记录并希望从第三页开始,则应该是20而不是23

答案 1 :(得分:1)

这不会(直接)回答如何在preInit中设置页面的问题,但它解决了我的问题。

我们可以使用stateLoadCallback从历史API加载状态(包括页面),而不是使用localStorage作为默认实现(即使在导航然后返回时也会记住状态)再次)。

$.extend(true, $.fn.dataTable.defaults, {
    stateSave: true,
    stateSaveCallback: (settings, data) => {
        let tableId = settings.nTable.id;
        if(!tableId) {
            // console.warn(`DataTable is missing an ID; cannot save its state`);
            return;
        }
        history.replaceState(_.set(['datatables', tableId], data, history.state), '');
    },
    stateLoadCallback: settings => {
        let tableId = settings.nTable.id;
        if(!tableId) {
            console.warn(`DataTable is missing an ID; cannot load its state`);
            return;
        }
        return _.get(['datatables', tableId], history.state) || null;
    }
});