[英]Blazor WASM working with dom elements without using JavaScript
[英]Using jQuery DataTable in Blazor WASM
我想将jQuery DataTable与我的 Blazor Wasm 项目集成。 所以我添加了对这些文件的引用:
//cdn.datatables.net/1.11.4/css/jquery.dataTables.min.css
//cdn.datatables.net/1.11.4/js/jquery.dataTables.min.js
并编写此 function 以调用适当的初始 function:
window.ApplyjQueryDatatable = () => {
$('#example').DataTable();
}
为了创建表格,我在 razor 页面中编写了以下代码:
@page "/"
@inject IJSRuntime JsRuntime
<div class="row mt-4 ">
<div class="col-12">
<table id="example" @ref="@DataTableContainer">
<thead>
<tr>
<th>OrderID</th>
<th>CustomerID</th>
<th>OrderDate</th>
<th>ShipCity</th>
<th>ShipPostalCode</th>
<th>ShipCountry</th>
</tr>
</thead>
<tbody>
@foreach (var item in OrderPage)
{
<tr>
<td>@item.OrderID</td>
<td>@item.CustomerID</td>
<td>@item.OrderDate</td>
<td>@item.ShipCity</td>
<td>@item.ShipPostalCode</td>
<td>@item.ShipCountry</td>
</tr>
}
</tbody>
</table>
</div>
</div>
@code {
private ElementReference DataTableContainer;
private List<Orders> OrderPage { set; get; } = new List<Orders>();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender == true)
{
//Web API Call Simulation
OrderPage = new List<Orders>();
OrderPage.Add(new Orders() { CustomerID = "aa1", OrderDate = DateTime.Now, OrderID = 1, ShipCity = "bb1", ShipCountry = "cc1", ShipPostalCode = "dd1" });
OrderPage.Add(new Orders() { CustomerID = "aa2", OrderDate = DateTime.Now, OrderID = 1, ShipCity = "bb2", ShipCountry = "cc2", ShipPostalCode = "dd2" });
OrderPage.Add(new Orders() { CustomerID = "aa3", OrderDate = DateTime.Now, OrderID = 1, ShipCity = "bb3", ShipCountry = "cc3", ShipPostalCode = "dd3" });
OrderPage.Add(new Orders() { CustomerID = "aa4", OrderDate = DateTime.Now, OrderID = 1, ShipCity = "bb4", ShipCountry = "cc4", ShipPostalCode = "dd4" });
OrderPage.Add(new Orders() { CustomerID = "aa5", OrderDate = DateTime.Now, OrderID = 1, ShipCity = "bb5", ShipCountry = "cc5", ShipPostalCode = "dd5" });
await JsRuntime.InvokeVoidAsync("ApplyjQueryDatatable");
StateHasChanged();
}
await base.OnAfterRenderAsync(firstRender);
}
}
运行项目后有2个问题:
我该如何解决这些问题?
谢谢
编辑 1)
根据@Henk的回答,我以这种方式更改了代码:
protected override async Task OnInitializedAsync()
{
var AllData = await apiServices.GetOrders();
OrderPage = AllData.Take(100).ToList();
//await JsRuntime.InvokeVoidAsync("ApplyjQueryDatatable");
}
和
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender == true)
{
await JsRuntime.InvokeVoidAsync("ApplyjQueryDatatable");
}
}
新问题是当表再次创建时,任何jQuery DataTable
功能都不起作用。 例如,如果我更改下拉记录数,则表将为空:
当我点击任何标题时:
我怎么解决这个问题? 谢谢
编辑 2)
再次根据@Henk评论:我以这种方式更改了代码并且它起作用了:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender == true)
{
var AllData = await apiServices.GetOrders();
OrderPage = AllData.Take(100).ToList();
StateHasChanged();
await JsRuntime.InvokeVoidAsync("ApplyjQueryDatatable");
}
base.OnAfterRender(firstRender);
}
我觉得有一个小点听。 如果我以这种方式更改代码:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender == true)
{
OrderPage = new List<OrdersDTO>();
OrderPage.Add(new OrdersDTO() { CustomerID = "aa1", OrderDate = DateTime.Now, OrderID = 1, ShipCity = "bb1", ShipCountry = "cc1", ShipPostalCode = "dd1" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa2", OrderDate = DateTime.Now, OrderID = 2, ShipCity = "bb2", ShipCountry = "cc2", ShipPostalCode = "dd2" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa3", OrderDate = DateTime.Now, OrderID = 3, ShipCity = "bb3", ShipCountry = "cc3", ShipPostalCode = "dd3" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa4", OrderDate = DateTime.Now, OrderID = 4, ShipCity = "bb4", ShipCountry = "cc4", ShipPostalCode = "dd4" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa5", OrderDate = DateTime.Now, OrderID = 5, ShipCity = "bb5", ShipCountry = "cc5", ShipPostalCode = "dd5" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa6", OrderDate = DateTime.Now, OrderID = 6, ShipCity = "bb6", ShipCountry = "cc6", ShipPostalCode = "dd6" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa7", OrderDate = DateTime.Now, OrderID = 7, ShipCity = "bb7", ShipCountry = "cc7", ShipPostalCode = "dd7" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa8", OrderDate = DateTime.Now, OrderID = 8, ShipCity = "bb8", ShipCountry = "cc8", ShipPostalCode = "dd8" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa9", OrderDate = DateTime.Now, OrderID = 9, ShipCity = "bb9", ShipCountry = "cc9", ShipPostalCode = "dd9" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa10", OrderDate = DateTime.Now, OrderID = 6, ShipCity = "bb10", ShipCountry = "cc10", ShipPostalCode = "dd10" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa11", OrderDate = DateTime.Now, OrderID = 6, ShipCity = "bb11", ShipCountry = "cc11", ShipPostalCode = "dd11" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa12", OrderDate = DateTime.Now, OrderID = 6, ShipCity = "bb12", ShipCountry = "cc12", ShipPostalCode = "dd12" });
StateHasChanged();
await JsRuntime.InvokeVoidAsync("ApplyjQueryDatatable");
}
base.OnAfterRender(firstRender);
}
如果行不通。 拉紧.......
但如果我这样写,它会起作用:
await Task.Run(() =>
{
OrderPage = new List<OrdersDTO>();
OrderPage.Add(new OrdersDTO() { CustomerID = "aa1", OrderDate = DateTime.Now, OrderID = 1, ShipCity = "bb1", ShipCountry = "cc1", ShipPostalCode = "dd1" });
OrderPage.Add(new OrdersDTO() { CustomerID = "aa2", OrderDate = DateTime.Now, OrderID = 2, ShipCity = "bb2", ShipCountry = "cc2", ShipPostalCode = "dd2" });
...
为什么这段代码会这样工作?
更新
随着异步加载,它变得更加毛茸茸。 jQuery 将捕获数据,这必须在正确的时刻发生。
bool loaded = false;
protected override async Task OnInitializedAsync()
{
await LoadData();
loaded = true;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (loaded)
{
loaded = false;
await JsRuntime.InvokeVoidAsync("ApplyjQueryDatatable");
}
}
旧答案
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender == true)
{
//Web API Call Simulation
// Do the async loading here
await JsRuntime.InvokeVoidAsync("ApplyjQueryDatatable");
//StateHasChanged(); -- remove
}
}
我知道我迟到了,但我目前在生产中使用的解决方案是创建我希望使用的表组件,例如: <ProductsDataTableComponent productModels="products"</ProductsDataTableComponent>
在这种情况下,您将在组件中添加一个期望您的表数据的参数,并在初始化时调用 AddDataTable js function 并包含 DataTablesDispose 的处置方法
@code
{
[Parameter]
public List<ProductModel> productModels { get; set; }
protected override async Task OnInitializedAsync()
{
await JS.InvokeVoidAsync("AddDataTable", "#productsTable");
}
void IDisposable.Dispose()
{
JS.InvokeVoidAsync("DataTablesDispose", "#productsTable");
}
}
重要的部分是将您的组件包装到围绕您的组件的 if 语句中,以确保在加载数据之前它不会被渲染。
所以最终结果看起来像这样:
@if(!(products?.Any() ?? false))
{
<div class="justify-content-center" style="font-size: 1.2em; text-align: center;">What ever you want to do when the data is empty aka don't render the table</div>
}
else
{
<ProductsDataTableComponent productModels="products"</ProductsDataTableComponent>
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.