Datatables.net: правильное разбиение на страницы сервера с помощью React Redux - PullRequest
1 голос
/ 30 октября 2019

У меня есть компонент реагирования, который отправляет запрос в API с использованием приставки. Этот запрос выполняет разбиение на страницы на стороне сервера.

Проблема в том, что я не понимаю, как выполнить эту нумерацию страниц в datatables.net с использованием redux.

Я знаю, как выполнить нумерацию страниц без таблиц данных (на самом деле, мой компонент выполняет это) и datatables имеет поддержку ajax , как пакет реагировать-редуцировать-данные . И то, и другое выполняет перенаправление вызова API через ajax, что не в случае использования приставки.

import React, { useEffect, useState, useCallback } from 'react'
import { bindActionCreators } from 'redux'

//...

const [skip, setSkip] = useState(10)
const [page, setPage] = useState(0)

// offset = 0 to page 0, offset 10 to page 1, offset 20 to page 2 and so on
<button onClick={() => props.doList({ offset: page * skip  })}>Request</button>

// Table shows the current 10 entries, from a max that is also 10.
<Table data={props.list} columns={predefinedColums}>

//...

// results are acessed by props.list
const mapStateToProps = (state) => {
    return ({
        list: state.reducer.list,
    })
}

const mapDispatchToProps = dispatch =>
    bindActionCreators(
        {
            doList,
        },
        dispatch
    )

В настоящее время я могу показать желаемые результаты, но не знаю, как выполнять новые вызовы при изменении страницы вкомпонент данных. API разбивки на страницы работает, поэтому, если я вручную изменяю номер страницы, он возвращает правильные записи.


//Table component

import React, { useEffect } from 'react'
import $ from 'jquery'
import 'datatables.net'
import 'datatables.net-responsive'
import 'datatables.net-select'

// other imports

function Table(props) {
    const { columns, data, title } = props

    useEffect(() => {
        $('#table_id').DataTable().destroy()
        $('#table_id').DataTable({
            retrieve: true,
            data,
            columns,
            "responsive": true,
            "lengthMenu": [
                [10, 25, 50, -1],
                [10, 25, 50, "All"]
            ],
            "language": {
                "emptyTable": i18n.t('emptyDataSourceMessage'),
                "paginate": {
                    "previous": i18n.t('Previous'),
                    "next": i18n.t('Next'),
                    "first": i18n.t("First"),
                    "last": i18n.t("Last"),
                },
                "infoFiltered": i18n.t("(filtered from _MAX_ total entries)"),
                "search": i18n.t('Search'),
                "info": i18n.t("Showing _START_ to _END_ of _TOTAL_ entries"),
                "infoEmpty": i18n.t("Showing 0 to 0 of 0 entries"),
            },
        })
    }, [columns, data])

    return (
        <div className="row">
            <div className="col s12">
                <div class="section section-data-tables">
                    <div className="card">
                        <div className="card-content">
                            <h4 className="card-title">{title}</h4>
                            <div className="row">
                                <div className="col s12">
                                    <table id="table_id" className="display">
                                        <thead>
                                            <tr>
                                                {columns.map((column, key) => <th key={key} data-field={column.field}>{column.title}</th>)}
                                            </tr>
                                        </thead>
                                        <tbody>
                                        </tbody>
                                        <tfoot>
                                            <tr>
                                                {columns.map((column, key) => <th key={key} data-field={column.field}>{column.title}</th>)}
                                            </tr>
                                        </tfoot>
                                    </table>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}

export default Table

Таблица выглядит следующим образом: (показаны 10 результатов из 10 и только страница)

enter image description here

Я хотел бы знать, как правильно выполнять разбиение на страницы на стороне сервера с помощью redux. В настоящее время возможно узнать количество записей, а также текущую страницу, которая будет отображаться.

1 Ответ

0 голосов
/ 06 ноября 2019

Просто нарежьте часть результатов, которые вы хотите вернуть клиенту (см. Первый раздел кода ниже). Кроме того, что я делаю, когда делаю пагинацию на стороне сервера, кеширую результат запроса, используя уникальный идентификатор. Это почти обязательно для предотвращения многократного повторного вычисления поиска каждый раз, когда пользователь переключает номер страницы или размер страницы.

Я запрашиваю некоторые результаты, как показано ниже:

  1. Клиент: отправьте запрос поиска (это также может быть идентификатор категории).

  2. Сервер: преобразование поиска в уникальный идентификатор. Посмотрите, есть ли результат уже в кеше. Если нет, вычислите поиск, поместите в кеш, ключом является уникальный идентификатор. Используя обычные операции с массивами (срез) в результатах поиска, я беру только нужную часть.

ret.productIDs =ret.productIDs.slice(imports.config.pageSizes[req.body.pageSize]*(req.body.pageNum), imports.config.pageSizes[req.body.pageSize]*(req.body.pageNum+1));

Сервер: верните его вместе с уникальным идентификатором поиска (чтобы в следующий раз он мог напрямую использовать этот идентификатор вместо поиска).

Клиент: отображение поискаРезультаты. Всякий раз, когда пользователь изменяет размер или номер страницы, отправьте этот запрос:

{
    searchId, pageNum, pageSizeIndex
}

Теперь вы также можете распространить это на сортировки, используя sortingIndex. Кроме того, на сервере вы ведете учет доступных сортировок результатов поиска, находящихся в кеше. Если запрос, запрашиваемый пользователем, еще не вычислен, просто отсортируйте одну из доступных (уже вычисленных сортировок) и добавьте ее к доступным сортировкам записи в кэше (для этого результата поиска). Таким образом, окончательный запрос выглядит так:

{
    searchId, pageNum, pageSizeIndex, sortingIndex
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...