Angular Virtual ForOf (仮想 ForOf) ディレクティブの概要
Ignite UI for Angular igxForOf ディレクティブは、膨大なデータをテンプレート化するための ngForOf の代替手段です。仮想化を使用して、DOM レンダリングとメモリ使用量を最適化します。
Angular 仮想スクロール ディレクティブの例
このサンプルが気に入りましたか? 完全な Ignite UI for Angularツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
Ignite UI for Angular Virtual ForOf ディレクティブを使用した作業の開始
Ignite UI for Angular igxFor
ディレクティブを使用した作業を開始するには、Ignite UI for Angular をインストールする必要があります。既存の Angular アプリケーションで、以下のコマンドを入力します。
ng add igniteui-angular
cmd
Ignite UI for Angular については、「はじめに」トピックをご覧ください。
次に、app.module.ts ファイルに IgxForOfModule
をインポートします。
// app.module.ts
import { IgxForOfModule } from 'igniteui-angular';
// import { IgxForOfModule } from '@infragistics/igniteui-angular'; for licensed package
@NgModule({
imports: [
...
IgxForOfModule,
...
]
})
export class AppModule {}
typescript
あるいは、16.0.0
以降、IgxForOfDirective
をスタンドアロンの依存関係としてインポートできます。
// home.component.ts
import { IgxForOfDirective } from 'igniteui-angular';
// import { IgxForOfDirective } from '@infragistics/igniteui-angular'; for licensed package
@Component({
selector: 'app-home',
template: `
<span #container>
<ng-template *igxFor="data"></ng-template>
</span>
`,
styleUrls: ['home.component.scss'],
standalone: true,
imports: [IgxForOfDirective]
})
export class HomeComponent {
public data: Employee [];
}
typescript
Ignite UI for Angular ForOf モジュールまたはディレクティブをインポートしたので、igxFor
ディレクティブの使用を開始できます。
Angular Virtual ForOf の使用
そのモジュールまたはディレクティブをインポートしたので、ローカル データにバインドする igxFor
の基本構成を設定します。
<span #container>
<ng-template *igxFor="data"></ng-template>
</span>
html
data プロパティは、仮想化 DOM の構築に使用されるデータ オブジェクトを提供する配列です。
例
igxFor
ディレクティブを使用して、データを垂直、水平、または両方向に仮想化できます。
仮想化はページング機能のようにデータをより小さいチャンクに分割します。このチャンクは、ユーザーがデータを水平/垂直にスクロールするときにコンテナー ビューポートで切り替わります。ページングの動作との違いは、仮想化が通常のスクロールバーの動作を装うことです。igxFor
ディレクティブはスクロール可能なコンテナーを作成して、データを分割して描画します。それは igxGrid
内で使用され、仮想 igx-list
を構築するために使用できます。
垂直仮想化
<igx-list>
<div [style.height]="'500px'" [style.overflow]="'hidden'" [style.position]="'relative'">
<igx-list-item [style.width]="'calc(100% - 18px)'"
*igxFor="let item of data | igxFilter: fo;
scrollOrientation : 'vertical';
containerSize: '500px';
itemSize: '50px'">
<div class="contact">
<span class="name">{{item.name}}</span>
</div>
</igx-list-item>
</div>
</igx-list>
html
注: igxForOf
テンプレートの親コンテナーには、次の CSS ルールが適用されていることを強く推奨します: 垂直方向には height
、水平方向には width
、overflow: hidden
および position: relative
。スムーズ スクロール動作が、表示されたままの場合にページのその他の部分に視覚的に影響を与えることが可能なコンテンツ オフセットによって実装されるためです。
水平仮想化
<igx-list>
<div [style.width]="'880px'" [style.overflow]="'hidden'" [style.position]="'relative'">
<igx-list-item [style.width]="'220px'"
*igxFor="let item of data | igxFilter: fo;
scrollOrientation : 'horizontal';
containerSize: '880px';
itemSize: '220px'">
<div class="contact">
<span class="name">{{item.name}}</span>
</div>
</igx-list-item>
</div>
</igx-list>
html
水平仮想化および垂直仮想化
<table #container [style.width]='width'
[style.height]='height'
[style.overflow]='"hidden"'
[style.position]='"relative"'>
<ng-template #scrollContainer igxFor let-rowData
[igxForOf]="data"
[igxForScrollOrientation]="'vertical'"
[igxForContainerSize]='height'
[igxForItemSize]='"50px"'>
<tr [style.display]="'flex'" [style.height]="'50px'">
<ng-template #childContainer igxFor let-col
[igxForOf]="cols"
[igxForScrollOrientation]="'horizontal'"
[igxForScrollContainer]="parentVirtDir"
[igxForContainerSize]='width'>
<td [style.min-width]='col.width + "px"'>
{{rowData[col.field]}}
</td>
</ng-template>
</tr>
</ng-template>
</table>
html
igxFor
ディレクティブは、igxGrid
内のデータを垂直方向と水平方向の両方向に仮想化するために使用されます。
より詳細な情報とデモについては、グリッド仮想化トピックに従ってください。
リモート サービスにバインドされる igxFor
igxForOf
ディレクティブは、Observable
プロパティ- remoteData
を使用してリモート サービスにバインドできます。(次の例の場合) chunkLoading
イベントも、データのリクエストをトリガーするために利用する必要があります。
<div style='height: 500px; overflow: hidden; position: relative;'>
<ng-template igxFor let-item [igxForOf]="remoteData | async"
(chunkPreload)="chunkLoading($event)"
[igxForScrollOrientation]="'vertical'"
[igxForContainerSize]='"500px"'
[igxForItemSize]='"50px"'
[igxForRemote]='true'
let-rowIndex="index" #virtDirRemote>
<div style='height:50px;'>{{item.ProductID}} : {{item.ProductName}}</div>
</ng-template>
</div>
html
注: igxForOf
のインスタンスで totalItemCount
プロパティを設定する必要があります。
this.virtDirRemote.totalItemCount = data['@odata.count'];
typescript
コンポーネントからディレクティブ インスタンスにアクセスするには、ViewChild
としてマークします。
@ViewChild('virtDirRemote', { read: IgxForOfDirective })
public virtDirRemote: IgxForOfDirective<any>;
typescript
最初のチャンクをロードするリクエストの後、totalItemCount
を設定できます:
public ngAfterViewInit() {
this.remoteService.getData(this.virtDirRemote.state, (data) => {
this.virtDirRemote.totalItemCount = data['@odata.count'];
});
}
typescript
データをリクエストする際、startIndex
プロパティと chunkSize
プロパティを提供する IgxForOfState
インターフェイスを利用できます。最初は chunkSize が 0 になるため、最初に読み込まれるチャンクのサイズを指定する必要があることに注意してください (最適な値は、初期の igxForContainerSize
を igxForItemSize
で割った値です)。
public getData(data?: IForOfState, cb?: (any) => void): any {
var dataState = data;
return this.http
.get(this.buildUrl(dataState))
.map((response) => response.json())
.map((response) => {
return response;
})
.subscribe((data) => {
this._remoteData.next(data.value);
if (cb) {
cb(data);
}
});
}
private buildUrl(dataState: any): string {
let qS: string = '?', requiredChunkSize: number;
if (dataState) {
const skip = dataState.startIndex;
requiredChunkSize = dataState.chunkSize === 0 ?
// Set initial chunk size, the best value is igxForContainerSize
// initially divided by igxForItemSize
10 : dataState.chunkSize;
const top = requiredChunkSize;
qS += `$skip=${skip}&$top=${top}&$count=true`;
}
return `${this.url}${qS}`;
}
typescript
chunkPreload
イベントが発生するたびに、新しいデータのチャンクがリクエストされます。
chunkLoading(evt) {
if(this.prevRequest){
this.prevRequest.unsubscribe();
}
this.prevRequest = this.remoteService.getData(evt, ()=> {
this.virtDirRemote.cdr.detectChanges();
});
}
typescript
ローカル変数
igxFor ディレクティブのコンテキストには、even
、odd
、first
、last
のヘルパー プロパティが含まれています。これらは、コレクション内の現在の要素の位置を識別するために使用されます。次のコードスニペットは、ng-template
で even
プロパティを使用する方法を示しています。すべての偶数の div 要素に even
クラスが割り当てられます:
<ng-template igxFor let-item let-isEven="even"
[igxForOf]="data"
[igxForScrollOrientation]="'vertical'" >
<div [ngClass]="{even: isEven}"></div>
</ng-template>
html
既知の制限
制限 | 説明 |
---|---|
初期化後にレンダリングされたテンプレートのコンテンツのサイズが変更された場合、scrollTo メソッドが正しく動作されません。 |
初期化後にランタイムを変更するサイズを持つテンプレート内の要素の場合 (コンテンツ プロジェクション、リモート要求の解決などの結果として)、scrollTo メソッドは正しいインデックスまでスクロールできません。メソッドは、ランタイムのサイズ変更が発生する前にインデックスの位置までスクロールし、サイズが変更された後は場所が正しくありません。回避策として、コンテンツが後で読み込まれた場合にコンテンツに基づいてサイズを変更しないテンプレートを使用します。 |