【问题标题】:Datatables.net Razor Page taking very long to load with larger data setsDatatables.net Razor 页面需要很长时间才能加载更大的数据集
【发布时间】:2021-04-09 18:57:12
【问题描述】:

我有一个功能齐全的页面,但是,我想使用 datatables.net 设置来实现搜索和排序功能......一旦你破解了几百条记录,它需要相当长的时间来加载。 10,000 条记录需要 3 分钟以上的时间才能加载页面并完全正常运行。有没有办法加快这个速度?我让分页工作,但它附带的搜索框只搜索该页面/记录集中的记录。有没有办法让它加载得更快(IE:让它在让它可排序之前渲染每条记录),还是我需要使用不同的方法?

这是页面:

@page
@model NBG_Central.Pages.DataCentral.ManageItemsModel

    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.23/css/jquery.dataTables.min.css" />
        <script language="javascript" src="https://code.jquery.com/jquery-3.5.1.js"></script>
        <script language="javascript" src="https://cdn.datatables.net/1.10.23/js/jquery.dataTables.min.js"></script>
    </head>
<h1>Manage Products</h1>
<div>
    <form method="post">
        <button asp-page="AddItem" class="btn btn-primary">Add Item</button>

        @if (Model.products.Count() > 0)
        {

            <table id="ProdTable" class="table table-striped border">
                <thead>
                    <tr class="table-secondary">
                        <th>
                            <label>ProdID</label>
                        </th>
                        <th>
                            <label>Product Description</label>
                        </th>
                        <th>
                            <label>Active</label>
                        </th>
                        <th>
                            <label>Sales Category</label>
                        </th>
                        <th>
                            <label>Prod Category</label>
                        </th>
                        <th>
                            <label>Genus</label>
                        </th>
                        <th>
                            <label>Variety</label>
                        </th>
                        <th>
                            <label>Color</label>
                        </th>
                        <th>
                            <label>Product Code</label>
                        </th>
                        <th>
                            <label>PPE Item #</label>
                        </th>
                        <th>
                            <label>NBG SKU</label>
                        </th>
                        <th>
                            <label>NBG UPC</label>
                        </th>
                        <th>
                            <label>GP Code</label>
                        </th>
                        <th>
                        </th>
                        <th>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var prod in Model.products)
                    {
                    <tr>
                        <td>
                            @Html.DisplayFor(m => prod.ProductID)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.ProductDesc)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.Active)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.ProductCategory)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.ProductionCategory)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.Genus)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.Variety)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.Color)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.ProductCode)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.PPEItemNumber)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.NBGSKU)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.NBGUPC)
                        </td>
                        <td>
                            @Html.DisplayFor(m => prod.GPCode)
                        </td>
                        <td>
                            <button asp-page-handler="Delete" asp-route-id="@prod.ProductID" onclick="return confirm('Are you sure')" class="btn btn-danger btn-sm">Delete</button>
                        </td>
                        <td>
                            <a asp-page="EditItem" asp-route-id="@prod.ProductID" class="btn btn-success btn-sm text-white">Edit</a>
                        </td>
                    </tr>
                    }
                </tbody>
            </table>
        }
        else
        {
            <p>No Records Available</p>
        }
    </form>
</div>

@section Scripts{

    <script>
        $(document).ready(function () {
            $('#ProdTable').DataTable();
        });
    </script>
}

尝试使用这样的代码隐藏处理分页,并让数据几乎立即加载。但是,这导致我只搜索该页面中的内容:

    public IEnumerable<Products> Items { get; set; }
    public Pager pager { get; set; }
    public SelectList TotalItemsList { get; set; }
    public int TotalItems { get; set; }
    public SelectList PageSizeList { get; set; }
    public int PageSize { get; set; }
    public SelectList MaxPagesList { get; set; }
    public int MaxPages { get; set; }
    public void OnGet(int p = 1)
    {
        TotalItemsList = new SelectList(new[] { 10, 150, 500, 1000, 5000, 10000, 50000, 100000, 1000000 });
        TotalItems = HttpContext.Session.GetInt32("TotalItems") ?? 150;
        PageSizeList = new SelectList(new[] { 1, 5, 10, 20, 50, 100, 200, 500, 1000 });
        PageSize = HttpContext.Session.GetInt32("PageSize") ?? 10;
        MaxPagesList = new SelectList(new[] { 1, 5, 10, 20, 50, 100, 200, 500 });
        MaxPages = HttpContext.Session.GetInt32("MaxPages") ?? 10;
        var products = _dataCentralDAL.GetAllProducts();
        pager = new Pager(products.Count(), p, PageSize, MaxPages);
        Items = products.Skip((pager.CurrentPage - 1) * pager.PageSize).Take(pager.PageSize);
    }

    public IActionResult OnPost(int totalItems, int pageSize, int maxPages)
    {
        HttpContext.Session.SetInt32("TotalItems", totalItems);
        HttpContext.Session.SetInt32("PageSize", pageSize);
        HttpContext.Session.SetInt32("MaxPages", maxPages);
        return Redirect("/Test/Pagination/");
    }

而且,使用这种方法,数据集可以通过 Console.Log() 显示它...但它实际上不会绑定到表格:

<script type="text/javascript" language="javascript" src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/js/jquery.dataTables.min.js"></script>

<script>
/////////
function convertToDataSet(responseJSON) {
    /*console.log(responseJSON);*/
    var returnList = [];
    var returnitem = [];
    for (var i = 0; i < responseJSON.length; i++) {
        //console.log(responseJSON[i]);
        returnitem = [];
        returnitem.push(responseJSON[i].productID);
        returnitem.push(responseJSON[i].productDesc);
        returnitem.push(responseJSON[i].active);
        returnitem.push(responseJSON[i].productCategory);
        returnitem.push(responseJSON[i].productionCategory);
        returnitem.push(responseJSON[i].productCode);
        returnitem.push(responseJSON[i].ppeItemNumber);
        returnitem.push(responseJSON[i].nbgsku);
        returnitem.push(responseJSON[i].nbgupc);
        returnitem.push(responseJSON[i].gpCode);
        returnitem.push(responseJSON[i].genus);
        returnitem.push(responseJSON[i].variety);
        returnitem.push(responseJSON[i].color);
        returnList.push(returnitem);
    }
    //console.log(returnList);
    return returnList;
}

function getTable() {
    return fetch('/Test/Pagination?Handler=Display',
        {
            method: 'get',
            headers: {
                'Content-Type': 'application/json;charset=UTF-8'
            }
        })
        .then(function (response) {
            if (response.ok) {
                return response.text();
            } else {
                throw Error('Response Not OK');
            }
        })
        .then(function (text) {
            try {
                return JSON.parse(text);
            } catch (err) {
                throw Error('Method Not Found');
            }
        })
        .then(function (responseJSON) {                
            var dataSet = convertToDataSet(responseJSON); 
            console.log(dataSet);
            $(document).ready(function () {
                $('#example').DataTable({
                    "data": dataSet,
                    "processing": true, // for show progress bar
                    "filter": true, // this is for disable filter (search box)
                    "orderMulti": false, // for disable multiple column at once
                    
                    columns: [
                        { title: "ProductID" },
                        { title: "ProductDesc" },
                        { title: "Active" },
                        { title: "ProductCategory" },
                        { title: "ProductionCategory" },
                        { title: "ProductCode" },
                        { title: "PPEItemNumber" },
                        { title: "NBGSKU" },
                        { title: "NBGUPC" },
                        { title: "GPCode" },
                        { title: "Genus" },
                        { title: "Variety" },
                        { title: "Color" },
                        
                        {
                            data: null, render: function (data, type, row) {
                                return '<a class="btn btn-danger" href="/InvoiceDelete?id=' + row[0] + '">Delete</a>';
                            }
                        },
                        {
                            "render": function (data, type, full, meta) { return '<a class="btn btn-info" href="/InvoiceEdit?id=' + full[0] + '">Edit</a>'; }
                        },
                        {
                            "render": function (data, type, full, meta) { return '<a class="btn btn-warning" href="/Index">Main Page</a>'; }
                        },
                    ]
                    
                });                    
            });
        })
}
getTable();
</script>
<table id="example" class="table table-striped border" style="width:100%">
<thead>
    <tr>
        <th>ProductID</th>
        <th>ProductDesc</th>
        <th>Active</th>
        <th>ProductCategory</th>
        <th>ProductionCategory</th>
        <th>ProductCode</th>
        <th>PPEItemNumber</th>
        <th>NBGSKU</th>
        <th>NBGUPC</th>
        <th>GPCode</th>
        <th>Genus</th>
        <th>Variety</th>
        <th>Color</th>
    </tr>
</thead>
</table>

【问题讨论】:

    标签: c# datatables razor-pages .net-5


    【解决方案1】:

    将 serverSide 选项设置为 true 以便您的分页和搜索在服务器端正常工作:

    $(document).ready(function() {
        $('#ProdTable').DataTable( {
            "processing": true,
            "serverSide": true
        } );
    } );
    

    【讨论】:

    【解决方案2】:

    好的,所以我无法让它与 Razor 页面一起使用,但我确实让它与 Blazor 一起使用。该页面大约有 4,000 条记录,加载时间约为 1-2 秒,并具有完整的 datatables.net 功能。

    我的 _host 文件:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Blazor</title>
        <base href="~/" />
        <environment include="Development">
            <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
        </environment>
        <environment exclude="Development">
            <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
                  asp-fallback-href="css/bootstrap/bootstrap.min.css"
                  asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                  crossorigin="anonymous"
                  integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" />
        </environment>
        <link href="css/site.css" rel="stylesheet" />
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/jq-3.3.1/dt-1.10.18/datatables.min.css" />
    </head>
    <body>
        <app>@(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))</app>
        <script src="_framework/blazor.server.js"></script>
        <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
        <script type="text/javascript" src="https://cdn.datatables.net/v/bs4/jq-3.3.1/dt-1.10.18/datatables.min.js"></script>
    </body>
    </html>
    

    还有,FetchData.razor 文件:

    @using BlazorDataTables.Data
    @using BlazorDataTables.Objects
    
    @inject WeatherForecastService ForecastService
    @inject IJSRuntime JSRuntime
    
    
    @if (product is null)
    {
        <p>Loading...</p>
    }
    else
    {
        <table class="table table-striped">
            <thead>
                <tr class="table-secondary">
                    <th>
                        <label>ProdID</label>
                    </th>
                    <th>
                        <label>Product Description</label>
                    </th>
                    <th>
                        <label>Active</label>
                    </th>
                    <th>
                        <label>Sales Category</label>
                    </th>
                    <th>
                        <label>Prod Category</label>
                    </th>
                    <th>
                        <label>Genus</label>
                    </th>
                    <th>
                        <label>Variety</label>
                    </th>
                    <th>
                        <label>Color</label>
                    </th>
                    <th>
                        <label>Product Code</label>
                    </th>
                    <th>
                        <label>PPE Item #</label>
                    </th>
                    <th>
                        <label>NBG SKU</label>
                    </th>
                    <th>
                        <label>NBG UPC</label>
                    </th>
                    <th>
                        <label>GP Code</label>
                    </th>
                    <th>
                    </th>
                    <th>
                    </th>
                </tr>
            </thead>
            <tbody>
                @foreach (var prod in product)
                {
                    <tr>
                        <td>
                            @prod.ProductID
                        </td>
                        <td>
                            @prod.ProductDesc
                        </td>
                        <td>
                            @prod.Active
                        </td>
                        <td>
                            @prod.ProductCategory
                        </td>
                        <td>
                            @prod.ProductionCategory
                        </td>
                        <td>
                            @prod.Genus
                        </td>
                        <td>
                            @prod.Variety
                        </td>
                        <td>
                            @prod.Color
                        </td>
                        <td>
                            @prod.ProductCode
                        </td>
                        <td>
                            @prod.PPEItemNumber
                        </td>
                        <td>
                            @prod.NBGSKU
                        </td>
                        <td>
                            @prod.NBGUPC
                        </td>
                        <td>
                            @prod.GPCode
                        </td>
                        <td>
                            <button class="btn btn-danger btn-sm" onclick="ShowHide(" test")">Delete</button>
                        </td>
                        <td>
                            @*<a href="@($"Admin/EditAdministrator/{administrator.Id}")" class="btn btn-primary table-btn">
                                    Edit
                                </a>*@
                            @*<a class="btn btn-success btn-sm text-white">Edit</a>*@
                        </td>
                    </tr>
    
                }
            </tbody>
        </table>
    }
    @code {
        private Product[] product;
    
        protected override async Task OnInitializedAsync()
        {
            product = ForecastService.GetInventories();
        }
    
        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                var jQuery = await JSRuntime.InvokeAsync<IJSObjectReference>("$", "table");
                await jQuery.InvokeVoidAsync("DataTable");
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-08-15
      • 1970-01-01
      • 1970-01-01
      • 2019-12-20
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      相关资源
      最近更新 更多