将 datatables.net 与服务器端 Blazor 应用程序一起使用

Posted

技术标签:

【中文标题】将 datatables.net 与服务器端 Blazor 应用程序一起使用【英文标题】:Using datatables.net with server-side Blazor application 【发布时间】:2020-09-22 09:14:48 【问题描述】:

我正在尝试将 datatables.net 与我的服务器端 Blazor 应用程序一起使用,我们将不胜感激。

我已经尝试了中途提到的代码 https://datatables.net/forums/discussion/56389/datatables-with-blazor,但是,我遇到的问题是当我在页面之间浏览时某些 UI 元素(例如分页)被复制。

下面是我的 _Host.cshtml 文件

@page "/"
@namespace MyApplication.Web.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@
    Layout = null;


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>MyApplication.Web</title>
    <base href="~/" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />    

    <script src="/lib/jquery/jquery.min.js"></script>
    <script src="/lib/datatables/js/jquery.dataTables.min.js"></script>
    <link href="/lib/datatables/css/jquery.dataTables.min.css" rel="stylesheet" />

</head>
<body>
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>

    <div id="blazor-error-ui">
        <environment include="Staging,Production">
            An error has occurred. This application may no longer respond until reloaded.
        </environment>
        <environment include="Development">
            An unhandled exception has occurred. See browser dev tools for details.
        </environment>
        <a href="" class="reload">Reload</a>
        <a class="dismiss">????</a>
    </div>   

    <script>
        function AddDataTable(table) 
            $(document).ready(function () 
                $(table).DataTable(
                    "searching": false
                );
            );
        
    </script>

    <script>
        function RemoveDataTable(table) 
            $(document).ready(function () 
                $(table).DataTable().destroy();
            );
        
    </script>

    <script src="_framework/blazor.server.js"></script>

</body>
</html>

下面是剃须刀组件的代码

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MyApplication.Shared.Entities;
using MyApplication.Web.Interfaces;

namespace MyApplication.Web.Pages.Admin

    public partial class ListAdministrators
    
        [Inject]
        public IAdministratorDataService AdministratorDataService  get; set; 

        [Inject]
        public NavigationManager NavigationManager  get; set; 

        public List<Administrator> Administrators  get; set; 

        protected override async Task OnInitializedAsync()
        
            Administrators = (await AdministratorDataService.GetAll()).ToList();
        

        protected void NavigateToAddAdministrator()
        
            NavigationManager.NavigateTo("/Admin/AdministratorEdit");
        

        protected override async Task OnAfterRenderAsync(bool firstRender)
        
            await JSRuntime.InvokeAsync<object>("AddDataTable", "#dataTable");
        
    

需要指出的是,在https://datatables.net/forums/discussion/56389/datatables-with-blazor 上,它们具有我在上面的代码中拥有的函数 RemoveDataTable 但是,我不确定如何在单击按钮之外调用此函数。

第一次加载 - 一切顺利

浏览到主页 - 仍然显示分页 UI 元素

【问题讨论】:

【参考方案1】:

我似乎已经用下面的方法解决了重复的 UI 元素问题,但是我很想知道是否有更好的方法,实际上,我确信一定有,所以问题应该是有多糟糕下面的方法?

_Host.cshtml 现在添加了以下内容

<script src="~/scripts/JSInterop.js"></script>
<script src="/lib/jquery/jquery.min.js"></script>
<script src="/lib/datatables/js/jquery.dataTables.min.js"></script>
<link href="/lib/datatables/css/jquery.dataTables.min.css" rel="stylesheet" />

创建了一个新组件DataTable.razor

@inject Microsoft.JSInterop.IJSRuntime JSRuntime;

    <div id="@id">
        @ChildContent
    </div>

@code

    [Parameter]
    public bool Searchable  get; set; 

    [Parameter]
    public RenderFragment ChildContent  get; set; 

    private string id  get; set;  = "DataTable-" + Guid.NewGuid().ToString();


    protected override void OnParametersSet()
    
        StateHasChanged();
        base.OnParametersSet();
    

    protected async override Task OnAfterRenderAsync(bool firstRender)
    
        await JSRuntime.InvokeAsync<string>("AddDataTable", new object[]  "#" + id + " table", Searchable );
        await base.OnAfterRenderAsync(firstRender);
    

创建了一个简单的 JS 文件 JSInterop.js

function AddDataTable(table, searching)     
    $(table).DataTable(
        "searching": searching
    );    

然后我在页面上创建数据表时使用下面的代码

<DataTable Searchable="true">
        <table class="table">
            <thead>
                <tr>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Access Level</th>
                    <th>Date Added</th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                @foreach (var administrator in Administrators)
                
                    <tr>
                        <td>@administrator.Id</td>
                        <td>@administrator.LastName</td>
                        <td>@administrator.AccessLevel.GetDisplayName()</td>
                        <td>@administrator.DateCreated.ToShortDateString()</td>
                        <td>
                            <a href="@($"Admin/EditAdministrator/administrator.Id")" class="btn btn-primary table-btn">
                                Edit
                            </a>
                        </td>
                    </tr>
                
            </tbody>
        </table>
    </DataTable>

【讨论】:

【参考方案2】:

我对此做了一些改进:

@inject Microsoft.JSInterop.IJSRuntime JSRuntime;

<table id="@id" class="table" style="width:100%" @attributes=UserAttributes>
    @ChildContent
</table>

@code

    [Parameter]
    public bool Searchable  get; set; 

    [Parameter]
    public RenderFragment ChildContent  get; set; 

    [Parameter]
    public string id  get; set;  = "DataTable-" + Guid.NewGuid().ToString();

    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string, object> UserAttributes  get; set; 


    protected override void OnParametersSet()
    
        StateHasChanged();
    

    protected async override Task OnAfterRenderAsync(bool firstRender)
    
        await JSRuntime.InvokeAsync<string>("AddDataTable", new object[]  $"#id", Searchable );        
    

我所做的是允许更自然地使用假设生成表格标签的组件并允许添加 css 属性的能力。现在该组件更具可重用性。

【讨论】:

以上是关于将 datatables.net 与服务器端 Blazor 应用程序一起使用的主要内容,如果未能解决你的问题,请参考以下文章

使用 Datatables.net 卡住的 Bootstrap 4 工具提示

用DataTables实现服务器端分页

datatables.net 搜索框 ajax

Bootstrap 4工具提示使用Datatables.net卡住了

将 datatables.js 与 asp.net gridview 集成

clusterize.js 可以与 datatables.net 一起使用吗?