Hierarchical Grid ロードオンデマンド
Ignite UI for React IgrHierarchicalGrid
は、要求するサーバーからのデータを最低限にすることによりすばやく描画できます。このため、ユーザーがビューで結果を確認でき、表示データをインタラクティブに操作できます。初期時にグリッドのデータのみが取得されて描画され、ユーザーが子グリッドを含む行を拡張した後のみ、特定の子グリッドのデータを取得します。このメカニズムは、ロードオンデマンドであらゆるリモートデータとの設定が簡単にできます。
このトピックは、既に利用可能なリモート サービスと通信してリモート サービス プロバイダーを作成し、ロードオンデマンドを設定する方法を説明します。以下は、デモと作成手順を示します。
React Hierarchical Grid ロードオンデマンドの例
リモート サービス プロバイダー
はじめにサービス プロバイダーを準備して階層グリッドに必要なデータを取得します。
基本データの取得
ブラウザーが提供する fetch()
グローバル関数を使用した HTTP プロトコルでバックエンドサービスと通信します。データを取得にはサービスのシンプルなメソッドが必要となります。
export function getData(dataState: any): any {
return fetch(buildUrl(dataState))
.then((result) => result.json());
}
buildUrl()
は取得したデータに基づいて url を生成するメソッドになります。実行された非同期のため、Promise を返します。それにより後でサブスクライブし、アプリケーションで処理を進めてグリッドへ渡すことができます。
要求 URL のビルド
次に GET 要求の URL をビルドする方法を定義します。メイン グリッドのデータを取得できますが含まれる子グリッドのデータも取得できます。ルート レベルにこちらの Customers
データを使用し、それ以外のレベルには Orders
と Details
を使用します。このモデルはアプリケーションごとに異なりますが、ここでは以下を使用します。
はじめに必要となるのはグリッドのデータ、親業のプライマリキーとその一意の ID をどこから取得するかを決定するテーブルの key
が必要です。
これらすべてを dataState
オブジェクトで定義します。例:
const dataState: {
key: string;
parentID: any;
parentKey: string;
rootLevel: boolean;
} = {
//...
};
function buildUrl(dataState: any) {
let qS = "";
if (dataState) {
if (dataState.rootLevel) {
qS += `${dataState.key}`;
} else {
qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
}
}
return `${URL}${qS}`;
}
結果
最後に、リモート サービスは以下のようになります。
const URL = `https://data-northwind.indigo.design/`;
export function getData(dataState: any): any {
return fetch(buildUrl(dataState))
.then((result) => result.json());
}
function buildUrl(dataState: any) {
let qS = "";
if (dataState) {
if (dataState.rootLevel) {
qS += `${dataState.key}`;
} else {
qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
}
}
return `${URL}${qS}`;
}
階層グリッドの`設定
次に階層グリッドを設定してリモート サービス プロバイダーに接続します。
テンプレートの地祇
最初に階層グリッド テンプレートを必要な階層レベルで定義します。customers のルート グリッド PrimaryKey
は最初のレベルの orders の customerId
です。orderId
と各 order 詳細の productId
です。各データベース テーブルとキーで初期テンプレートを定義します。
<IgrHierarchicalGrid ref={hierarchicalGrid} primaryKey="customerId" height="600px">
<IgrColumn field="customerId" hidden={true}></IgrColumn>
<IgrColumn field="companyName" header="Company Name"></IgrColumn>
<IgrColumn field="contactName" header="Contact Name"></IgrColumn>
<IgrColumn field="contactTitle" header="Contact Title"></IgrColumn>
<IgrColumn field="address.country" header="Country"></IgrColumn>
<IgrColumn field="address.phone" header="Phone"></IgrColumn>
<IgrRowIsland childDataKey="Orders" primaryKey="orderId">
<IgrColumn field="orderId" hidden={true}></IgrColumn>
<IgrColumn field="shipAddress.country" header="Ship Country"></IgrColumn>
<IgrColumn field="shipAddress.city" header="Ship City"></IgrColumn>
<IgrColumn field="shipAddress.street" header="Ship Address"></IgrColumn>
<IgrColumn field="orderDate" header="Order Date" dataType="date"></IgrColumn>
<IgrRowIsland childDataKey="Details" primaryKey="productId">
<IgrColumn field="productId" hidden={true}></IgrColumn>
<IgrColumn field="quantity" header="Quantity"></IgrColumn>
<IgrColumn field="unitPrice" header="Unit Price"></IgrColumn>
<IgrColumn field="discount" header="Discount"></IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
</IgrHierarchicalGrid>
ルート レベル階層グリッドと最終的にはその子のデータがテンプレートに必要となります。
ref={hierarchicalGrid}
参照が使用できるため、コードでサービスからデータ取得後にルート グリッドのデータを簡単に設定できます。
展開されている子にデータを設定する方法は異なります。行がはじめて展開されたときに新し子 IgrHierarchicalGrid
が描画がされるため、データを設定するために新しく作成されたグリッドの参照を取得する必要があります。各 IgrRowIsland
コンポーネントに GridCreated
イベントがあり、特定の子アイランドに新しい子グリッドが作成されたときに発生します。新しいグリッドの参照を取得するために使用でき、サービスからデータを要求して適用します。
サービスをビルドしているためルートレベルの場合に情報のみが必要なため、すべてのアイランドに 1 メソッドを使用できます。このすべての情報には、イベント引数から直接またはイベントをトリガーする行アイランドからアクセスできます。
gridCreated
を使用するメソッドに名前を付けます。
GridCreated
イベントは行アイランド、parentID
プロパティ、および新しい子グリッド プロパティへの参照を提供するため、これは最初と 2 番目の引数として渡されます。親行の primaryKey
についての情報はありませんが、バインドした行アイランドに基づいて 2 番目の引数として簡単に渡すことができます。
変更を加えたテンプレート ファイルは以下のようになります。
<IgrHierarchicalGrid ref={hierarchicalGrid} primaryKey="customerId" height="600px">
<IgrColumn field="customerId" hidden={true}></IgrColumn>
<IgrColumn field="companyName" header="Company Name"></IgrColumn>
<IgrColumn field="contactName" header="Contact Name"></IgrColumn>
<IgrColumn field="contactTitle" header="Contact Title"></IgrColumn>
<IgrColumn field="address.country" header="Country"></IgrColumn>
<IgrColumn field="address.phone" header="Phone"></IgrColumn>
<IgrRowIsland
childDataKey="Orders"
primaryKey="orderId"
gridCreated={(
rowIsland: IgrRowIsland,
e: IgrGridCreatedEventArgs
) => gridCreated(rowIsland, e, "Customers")}
>
<IgrColumn field="orderId" hidden={true}></IgrColumn>
<IgrColumn field="shipAddress.country" header="Ship Country"></IgrColumn>
<IgrColumn field="shipAddress.city" header="Ship City"></IgrColumn>
<IgrColumn field="shipAddress.street" header="Ship Address"></IgrColumn>
<IgrColumn field="orderDate" header="Order Date" dataType="date"></IgrColumn>
<IgrRowIsland
childDataKey="Details"
primaryKey="productId"
gridCreated={(
rowIsland: IgrRowIsland,
e: IgrGridCreatedEventArgs
) => gridCreated(rowIsland, e, "Orders")}
>
<IgrColumn field="productId" hidden={true}></IgrColumn>
<IgrColumn field="quantity" header="Quantity"></IgrColumn>
<IgrColumn field="unitPrice" header="Unit Price"></IgrColumn>
<IgrColumn field="discount" header="Discount"></IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
</IgrHierarchicalGrid>
サービスへ接続
最後の手順の 1 つとして、以前作成したサービスに階層グリッドを接続することです。
useRef
React フックを介してルート グリッドへの参照を取得し、そのデータを設定します。
const hierarchicalGrid = useRef<IgrHierarchicalGrid>(null);
グリッドがサービスのデータを要求して割り当てる前に描画されることを確認するために、useEffect
React フックを使用します。親がないため、rootLevel
は true でそのキーのみをサービスの getData
へ渡すことができます。サブスクライブする必要のある Promise を返します。
useEffect(() => {
getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
(data: any) => {
hierarchicalGrid.current.data = data;
hierarchicalGrid.current.markForCheck();
}
);
}, []);
次に作成した新しい子グリッドのデータを要求する gridCreated
メソッドを作成する必要があります。
ルート レベル グリッド データの取得と同様に、ここではparentID
や parentKey
などの情報を渡す必要があります。rootLevel
はいずれの子も false です。
function gridCreated(rowIsland: IgrRowIsland, event: IgrGridCreatedEventArgs, _parentKey: string) {
const context = event.detail;
const dataState = {
key: rowIsland.childDataKey,
parentID: context.parentID,
parentKey: _parentKey,
rootLevel: false,
};
getData(dataState).then((data: any[]) => {
context.grid.data = data;
context.grid.markForCheck();
});
}
これにより、アプリケーションの設定はほぼ完了です。最後の手順は、空グリッドを表示する代わりにユーザーにデータがまだ読み込み中であることを通知してユーザー エクスペリエンスを向上します。IgrHierarchicalGrid
は、グリッドが空のときに表示できるインジケーターの読み込みサポートします。新しいデータが取得されると読み込みインジケーターが非表示となりデータが描画されます。
読み込み通知の設定
IgrHierarchicalGrid
は、IsLoading
プロパティを true に設定して読み込みインジケーターを表示できます。データが読み込まれるまでルートグリッドにあらかじめ設定しますが、新しい子グリッドを作成する際にも必要です。テンプレートで常に true に設定できますが、false に設定してサービスが空配列を返した場合は非表示にしてデータのないグリッドを表示できます。
以下は構成の最終バージョンです。
const hierarchicalGrid = useRef<IgrHierarchicalGrid>(null);
useEffect(() => {
hierarchicalGrid.current.isLoading = true;
getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
(data: any) => {
hierarchicalGrid.current.isLoading = false;
hierarchicalGrid.current.data = data;
hierarchicalGrid.current.markForCheck();
}
);
}, []);
function gridCreated(rowIsland: IgrRowIsland, event: IgrGridCreatedEventArgs, _parentKey: string) {
const context = event.detail;
const dataState = {
key: rowIsland.childDataKey,
parentID: context.parentID,
parentKey: _parentKey,
rootLevel: false,
};
context.grid.isLoading = true;
getData(dataState).then((data: any[]) => {
context.grid.isLoading = false;
context.grid.data = data;
context.grid.markForCheck();
});
}
API リファレンス
その他のリソース
コミュニティに参加して新しいアイデアをご提案ください。