Hierarchical Grid ロードオンデマンド

    Ignite UI for Blazor IgbHierarchicalGrid は、要求するサーバーからのデータを最低限にすることによりすばやく描画できます。このため、ユーザーがビューで結果を確認でき、表示データをインタラクティブに操作できます。初期時にグリッドのデータのみが取得されて描画され、ユーザーが子グリッドを含む行を拡張した後のみ、特定の子グリッドのデータを取得します。このメカニズムは、ロードオンデマンドであらゆるリモートデータとの設定が簡単にできます。

    このトピックは、既に利用可能なリモート サービスと通信してリモート サービス プロバイダーを作成し、ロードオンデマンドを設定する方法を説明します。以下は、デモと作成手順を示します。

    Blazor Hierarchical Grid ロードオンデマンドの例

    リモート サービス プロバイダー

    はじめにサービス プロバイダーを準備して階層グリッドに必要なデータを取得します。

    基本データの取得

    ブラウザーが提供する fetch() グローバル関数を使用した HTTP プロトコルでバックエンドサービスと通信します。データを取得にはサービスのシンプルなメソッドが必要となります。

    function getData(dataState) {
        return fetch(buildUrl(dataState))
            .then((result) => result.json());
    }
    

    buildUrl() は取得したデータに基づいて url を生成するメソッドになります。実行された非同期のため、Promise を返します。それにより後でサブスクライブし、アプリケーションで処理を進めてグリッドへ渡すことができます。

    要求 URL のビルド

    次に GET 要求の URL をビルドする方法を定義します。メイン グリッドのデータを取得できますが含まれる子グリッドのデータも取得できます。ルート レベルにこちらCustomers データを使用し、それ以外のレベルには OrdersDetails を使用します。このモデルはアプリケーションごとに異なりますが、ここでは以下を使用します。

    はじめに必要となるのはグリッドのデータ、親業のプライマリキーとその一意の ID をどこから取得するかを決定するテーブルの key が必要です。

    これらすべてを dataState オブジェクトで定義します。例:

    const dataState: {
        key: string;
        parentID: any;
        parentKey: string;
        rootLevel: boolean;
    } = {
        //...
    };
    
    function buildUrl(dataState) {
        let qS = "";
        if (dataState) {
            if (dataState.rootLevel) {
                qS += `${dataState.key}`;
            } else {
                qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
            }
        }
        return `${DATA_URL}${qS}`;
    }
    

    結果

    最後に、リモート サービスは以下のようになります。

    const DATA_URL = `https://data-northwind.indigo.design/`;
    
    function getData(dataState) {
        return fetch(buildUrl(dataState))
            .then((result) => result.json());
    }
    
    function buildUrl(dataState) {
        let qS = "";
        if (dataState) {
            if (dataState.rootLevel) {
                qS += `${dataState.key}`;
            } else {
                qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
            }
        }
        return `${DATA_URL}${qS}`;
    }
    

    階層グリッドの`設定

    次に階層グリッドを設定してリモート サービス プロバイダーに接続します。

    テンプレートの地祇

    最初に階層グリッド テンプレートを必要な階層レベルで定義します。customers のルート グリッド PrimaryKey は最初のレベルの orders の customerId です。orderId と各 order 詳細の productId です。各データベース テーブルとキーで初期テンプレートを定義します。

    <IgbHierarchicalGrid Id="hGrid" PrimaryKey="customerId" Height="600px">
        <IgbColumn Field="customerId" Hidden="true"></IgbColumn>
        <IgbColumn Field="companyName" Header="Company Name"></IgbColumn>
        <IgbColumn Field="contactName" Header="Contact Name"></IgbColumn>
        <IgbColumn Field="contactTitle" Header="Contact Title"></IgbColumn>
        <IgbColumn Field="address.country" Header="Country"></IgbColumn>
        <IgbColumn Field="address.phone" Header="Phone"></IgbColumn>
        <IgbRowIsland ChildDataKey="Orders" PrimaryKey="orderId">
            <IgbColumn Field="orderId" Hidden="true"></IgbColumn>
            <IgbColumn Field="shipAddress.country" Header="Ship Country"></IgbColumn>
            <IgbColumn Field="shipAddress.city" Header="Ship City"></IgbColumn>
            <IgbColumn Field="shipAddress.street" Header="Ship Address"></IgbColumn>
            <IgbColumn Field="orderDate" Header="Order Date" DataType="GridColumnDataType.Date"></IgbColumn>
            <IgbRowIsland ChildDataKey="Details" PrimaryKey="productId">
                <IgbColumn Field="productId" Hidden="true"></IgbColumn>
                <IgbColumn Field="quantity" Header="Quantity"></IgbColumn>
                <IgbColumn Field="unitPrice" Header="Unit Price"></IgbColumn>
                <IgbColumn Field="discount" Header="Discount"></IgbColumn>
            </IgbRowIsland>
        </IgbRowIsland>
    </IgbHierarchicalGrid>
    

    ルート レベル階層グリッドと最終的にはその子のデータがテンプレートに必要となります。

    Id="hGrid" 参照が使用できるため、コードでサービスからデータ取得後にルート グリッドのデータを簡単に設定できます。

    展開されている子にデータを設定する方法は異なります。行がはじめて展開されたときに新し子 IgbHierarchicalGrid が描画がされるため、データを設定するために新しく作成されたグリッドの参照を取得する必要があります。各 IgbRowIsland コンポーネントに GridCreated イベントがあり、特定の子アイランドに新しい子グリッドが作成されたときに発生します。新しいグリッドの参照を取得するために使用でき、サービスからデータを要求して適用します。

    サービスをビルドしているためルートレベルの場合に情報のみが必要なため、すべてのアイランドに 1 メソッドを使用できます。このすべての情報には、イベント引数から直接またはイベントをトリガーする行アイランドからアクセスできます。

    OnGridCreated を使用するメソッドに名前を付けます。

    GridCreated イベントは parentID プロパティ、owner として行アイランドへの参照、新しい子 grid プロパティを提供するため、最初の引数として渡されます。親行の primaryKey についての情報しかありませんが、行アイランドの ChildDataKey に基づいてそれを簡単に判断できます。

    変更を加えたテンプレート ファイルは以下のようになります。

    <IgbHierarchicalGrid Id="hGrid" PrimaryKey="customerId" Height="600px">
        <IgbColumn Field="customerId" Hidden="true"></IgbColumn>
        <IgbColumn Field="companyName" Header="Company Name"></IgbColumn>
        <IgbColumn Field="contactName" Header="Contact Name"></IgbColumn>
        <IgbColumn Field="contactTitle" Header="Contact Title"></IgbColumn>
        <IgbColumn Field="address.country" Header="Country"></IgbColumn>
        <IgbColumn Field="address.phone" Header="Phone"></IgbColumn>
        <IgbRowIsland ChildDataKey="Orders" PrimaryKey="orderId" GridCreatedScript="OnGridCreated">
            <IgbColumn Field="orderId" Hidden="true"></IgbColumn>
            <IgbColumn Field="shipAddress.country" Header="Ship Country"></IgbColumn>
            <IgbColumn Field="shipAddress.city" Header="Ship City"></IgbColumn>
            <IgbColumn Field="shipAddress.street" Header="Ship Address"></IgbColumn>
            <IgbColumn Field="orderDate" Header="Order Date" DataType="GridColumnDataType.Date"></IgbColumn>
            <IgbRowIsland ChildDataKey="Details" PrimaryKey="productId" GridCreatedScript="OnGridCreated">
                <IgbColumn Field="productId" Hidden="true"></IgbColumn>
                <IgbColumn Field="quantity" Header="Quantity"></IgbColumn>
                <IgbColumn Field="unitPrice" Header="Unit Price"></IgbColumn>
                <IgbColumn Field="discount" Header="Discount"></IgbColumn>
            </IgbRowIsland>
        </IgbRowIsland>
    </IgbHierarchicalGrid>
    

    サービスへ接続

    最後の手順の 1 つとして、以前作成したサービスに階層グリッドを接続することです。

    ルート グリッドへの参照を取得して、そのデータを設定します。グリッドがサービスのデータを要求して割り当てる前に描画されることを確認するために、Rendered イベントを使用します。親がないため、rootLeveltrue でそのキーのみをサービスの getData へ渡すことができます。サブスクライブする必要のある Promise を返します。

    igRegisterScript("OnGridRendered", () => {
        const grid = document.getElementById("hGrid");
    
        getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
            (data) => {
                grid.data = data;
                grid.markForCheck();
            });
    }, false)
    

    次に作成した新しい子グリッドのデータを要求する OnGridCreated メソッドを作成する必要があります。

    ルート レベル グリッド データの取得と同様に、ここではparentIDparentKey などの情報を渡す必要があります。rootLevel はいずれの子も false です。

    igRegisterScript("OnGridCreated", (args) => {
        const context = args.detail;
        const _parentKey = context.owner.childDataKey === "Orders" ? "Customers" : "Orders";
        const dataState = {
            key: context.owner.childDataKey,
            parentID: context.parentID,
            parentKey: _parentKey,
            rootLevel: false,
        };
    
        getData(dataState).then((data) => {
            context.grid.data = data;
            context.grid.markForCheck();
        });
    }, false)
    

    これにより、アプリケーションの設定はほぼ完了です。最後の手順は、空グリッドを表示する代わりにユーザーにデータがまだ読み込み中であることを通知してユーザー エクスペリエンスを向上します。IgbHierarchicalGrid は、グリッドが空のときに表示できるインジケーターの読み込みサポートします。新しいデータが取得されると読み込みインジケーターが非表示となりデータが描画されます。

    読み込み通知の設定

    IgbHierarchicalGrid は、IsLoading プロパティを true に設定して読み込みインジケーターを表示できます。データが読み込まれるまでルートグリッドにあらかじめ設定しますが、新しい子グリッドを作成する際にも必要です。テンプレートで常に true に設定できますが、false に設定してサービスが空配列を返した場合は非表示にしてデータのないグリッドを表示できます。

    以下は構成の最終バージョンです。

    igRegisterScript("OnGridRendered", () => {
        const grid = document.getElementById("hGrid");
    
        grid.isLoading = true;
    
        getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
            (data) => {
                grid.isLoading = false;
                grid.data = data;
                grid.markForCheck();
            });
    }, false)
    
    igRegisterScript("OnGridCreated", (args) => {
        const context = args.detail;
        const _parentKey = context.owner.childDataKey === "Orders" ? "Customers" : "Orders";
        const dataState = {
            key: context.owner.childDataKey,
            parentID: context.parentID,
            parentKey: _parentKey,
            rootLevel: false,
        };
    
        context.grid.isLoading = true;
    
        getData(dataState).then((data) => {
            context.grid.isLoading = false;
            context.grid.data = data;
            context.grid.markForCheck();
        });
    }, false)
    

    API リファレンス

    その他のリソース

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