Blazor Grid のリモート データ操作
デフォルトで、IgbGrid
は独自のロジックを使用してデータ操作を実行します。
これらのタスクをリモートで実行し、IgbGrid
で公開される特定の入力とイベントを使用して IgbGrid
に結果のデータを供給できます。
無限スクロール
エンドポイントからデータを分割して取得するシナリオの一般的なデザインは、無限スクロールです。データ グリッドの場合、エンドユーザーが一番下までスクロールすることによってトリガーされたロードデータが連続的に増加します。次の段落では、使用可能な API を使用して IgbGrid
で無限スクロールを簡単に実現する方法について説明します。
無限スクロールを実装するには、データを分割してフェッチする必要があります。すでにフェッチされたデータはローカルに保存し、チャンクの長さおよび数を決定する必要があります。また、グリッドで最後に表示されるデータ行インデックスを追跡する必要があります。このように、StartIndex
と ChunkSize
プロパティを使用して、ユーザーが上にスクロールして既にフェッチしたデータを表示するか、下にスクロールしてエンドポイントからさらにデータをフェッチする必要があるかを決定できます。
最初に、データの最初のチャンクをフェッチします。TotalItemCount
プロパティはグリッドがスクロールバーのサイズを正しく設定できるようにするために重要です。
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var grid = this.grid;
grid.IsLoading = true;
double dataViewSize = 480.0 / 50.0;
this.PageSize = Convert.ToInt32(Math.Floor(dataViewSize * 1.5));
var data = await GetDataRemote(1, this.PageSize);
this.CachedData = data;
this.LocalData = this.CachedData;
grid.TotalItemCount = (this.PageSize * this.Page) + 1;
double pageCount = Math.Ceiling((double)this.TotalItems / (double)this.PageSize);
this.TotalPageCount = (int)pageCount;
grid.IsLoading = false;
StateHasChanged();
}
}
}
さらに、DataPreLoad
出力にサブスクライブする必要があります。これにより、グリッドが現在ロードされているものではなく、異なるチャンクを表示しようとするときに必要なデータを提供できます。イベント ハンドラーで、ローカルに既にキャッシュされている新しいデータをフェッチするか、データを返すかを決定する必要があります。
<IgbGrid AutoGenerate="false"
Height="480px"
Name="grid"
Id="grid"
Data="LocalData"
@ref="grid"
DataPreLoad="OnDataPreLoad">
<IgbColumn Name="ID"
Field="ProductID"
Header="ID">
</IgbColumn>
<IgbColumn Name="ProductName"
Field="ProductName"
Header="Product Name">
</IgbColumn>
<IgbColumn Name="QuantityPerUnit"
Field="QuantityPerUnit"
Header="Quantity Per Unit">
</IgbColumn>
<IgbColumn Name="UnitPrice"
Field="UnitPrice"
Header="Unit Price">
</IgbColumn>
<IgbColumn Name="OrderDate"
Field="OrderDate"
Header="Order Date">
</IgbColumn>
<IgbColumn Name="Discontinued"
Field="Discontinued"
Header="Discontinued">
</IgbColumn>
</IgbGrid>
@code {
private IgbGrid grid;
public async void OnDataPreLoad(IgbForOfStateEventArgs e)
{
int chunkSize = (int)e.Detail.ChunkSize;
int startIndex = (int)e.Detail.StartIndex;
int totalCount = (int)this.grid.TotalItemCount;
bool isLastChunk = totalCount == startIndex + chunkSize;
// when last chunk reached load another page of data
if (isLastChunk)
{
if (this.TotalPageCount == this.Page)
{
this.LocalData = this.CachedData.Skip(startIndex).Take(chunkSize).ToList();
return;
}
// add next page of remote data to cache
this.grid.IsLoading = true;
this.Page++;
var remoteData = await GetDataRemote(this.Page, this.PageSize);
this.CachedData.AddRange(remoteData);
var data = this.CachedData.Skip(startIndex).Take(chunkSize);
this.LocalData = data.ToList();
this.grid.IsLoading = false;
this.grid.TotalItemCount = Math.Min(this.Page * this.PageSize, this.TotalItems);
}
else
{
var data = this.CachedData.Skip(startIndex).Take(chunkSize).ToList();
this.LocalData = data;
}
}
}
無限スクロールのデモ
リモート ページング
ページング機能はリモート データで処理することもできます。はじめにデータ フェッチングを行うサービスを宣言します。ページ カウントを計算するためすべてのデータ項目のカウントをが必要なため、ロジックをサービスに追加する必要があります。
Blazor Server はすでにリモート インスタンスであるため、他のプラットフォームのデモとは異なり、データがすでにリモートであるため、データ用に別のリモート インスタンスを設定する必要はありません。リモート ページングを行うには、データ クラスにいくつかのメソッドを設定する必要があります。
public Task<List<NwindDataItem>> GetData(int index, int perPage)
{
var itemsToReturn = items.Skip(index).Take(perPage).ToList();
return Task.FromResult(itemsToReturn);
}
public Task<int> GetDataLength()
{
return Task.FromResult(items.Count);
}
サービスを宣言した後にコンポーネントを作成する必要があり、IgbGrid
コンストラクションとデータ サブスクリプションを処理します。
まず、グリッドにデータを読み込む必要があります。タイミングの問題を回避するには、グリッドが描画された後に実行することをお勧めします。
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await Paginate(0, PerPage);
totalRecordsCount = await NwindDataService.GetDataLength();
StateHasChanged();
}
}
その後は、ページング イベントをカスタム メソッドにバインドするだけで、リモート ページングが設定されます。
<IgbPaginator @ref="pager" PageChange="OnPageChange" PerPageChange="OnPerPageChange" TotalRecords="totalRecordsCount"></IgbPaginator>
....
@code {
private async void OnPerPageChange(IgbNumberEventArgs e)
{
PerPage = e.Detail;
await Paginate(0, e.Detail);
}
private async void OnPageChange(IgbNumberEventArgs e)
{
await Paginate(e.Detail, PerPage);
}
...
private async Task Paginate(double page, double perPage)
{
this.page = page;
double skip = this.page * PerPage;
double top = PerPage;
try
{
data = await NwindDataService.GetData(Convert.ToInt32(skip), Convert.ToInt32(perPage));
isLoading = false;
UpdateUI();
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error fetching data: {ex.Message}");
}
}
}
詳細については、以下の完全なデモをご覧ください。
グリッド リモート ページングのデモ
既知の問題と制限
- グリッドに
PrimaryKey
が設定されておらず、リモート データ シナリオが有効になっている場合 (ページング、ソート、フィルタリング、スクロール時に、グリッドに表示されるデータを取得するためのリモート サーバーへのリクエストがトリガーされる場合)、データ要求が完了すると、行は次の状態を失います:
- 行の選択
- 行の展開/縮小
- 行の編集
- 行のピン固定
API リファレンス
その他のリソース
コミュニティに参加して新しいアイデアをご提案ください。