Close
Angular React Web Components Blazor Blazor
Premium

Blazor Grid のリモート データ操作

デフォルトで、IgbGrid は独自のロジックを使用してデータ操作を実行します。

これらのタスクをリモートで実行し、IgbGrid によって公開される特定の入力とイベントを利用することで、結果として得られたデータを IgbGrid にフィードできます。

無限スクロール

エンドポイントからデータを分割して取得するシナリオの一般的な設計は、無限スクロールです。データ グリッドの場合、エンドユーザーが一番下までスクロールするたびに追加のデータが読み込まれ、表示されるデータが継続的に増えていくのが特徴です。次の段落では、使用可能な API を使用して IgbGrid で無限スクロールを簡単に実現する方法について説明します。

無限スクロールを実装するには、データをチャンク単位で取得する必要があります。既に取得したデータはローカルに保存し、チャンクの長さといくつのチャンクがあるかを判断する必要があります。また、グリッドで最後に表示されているデータ行のインデックスを追跡しておく必要があります。これにより、IgbForOfState.ChunkSizeIgbForOfState.StartIndex プロパティを使用して、ユーザーが上にスクロールして既に取得済みのデータを表示する必要があるか、下にスクロールしてエンドポイントからさらにデータを取得する必要があるかを判断できます。

最初に、データの最初のチャンクを取得します。IgbGrid.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();
            }

        }
}

さらに、IgbGrid.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}");
        }
    }
}

詳細については、以下の完全なデモを確認してください。

グリッド リモート ページングのデモ

既知の問題と制限

グリッドに IgbGrid.PrimaryKey が設定されておらず、リモート データのシナリオが有効になっている場合 (ページング、ソート、フィルタリング、スクロールによってリモート サーバーへの要求がトリガーされ、グリッドに表示するデータを取得する場合)、データ要求が完了すると、行は次の状態を失います。

  • 行の選択
  • 行の展開/折りたたみ
  • 行の編集
  • 行のピン留め

API リファレンス

IgbGrid IgbPaginator

その他のリソース

コミュニティに参加して新しいアイデアをご提案ください。