Close
Angular React Web Components Blazor Angular
Open Source

Angular Virtual ForOf (仮想 ForOf) ディレクティブの概要

igxForOf ディレクティブは非推奨です。単一の軸を仮想化する新しいリストには、代わりに Virtual Scroll コンポーネントを使用してください。既存のリストは引き続き動作します。Virtual Scroll は実行時に項目を測定するため項目ごとに異なるサイズを使用でき、独自のスクロール コンテナーも作成します。既存のリストを移行する方法については、igxForOf リストを Virtual Scroll に置き換えるにはどうすればよいですか?を参照してください。

Ignite UI for Angular の igxForOf ディレクティブは、大量のデータをテンプレート化するための ngForOf の代替となるディレクティブです。内部で仮想化を使用して、DOM のレンダリングとメモリ消費を最適化します。

Angular 仮想スクロール ディレクティブの例

Ignite UI for Angular Virtual ForOf ディレクティブを使用した作業の開始

Ignite UI for Angular igxFor ディレクティブを使用した作業を開始するには、Ignite UI for Angular をインストールする必要があります。既存の Angular アプリケーションで、以下のコマンドを入力します。

ng add igniteui-angular

Ignite UI for Angular については、「はじめに」トピックをご覧ください。

次に、app.module.ts ファイルに IgxForOfModule をインポートします。

// app.module.ts

import { IgxForOfModule } from 'igniteui-angular/directives';
// import { IgxForOfModule } from '@infragistics/igniteui-angular'; for licensed package

@NgModule({
    imports: [
        ...
        IgxForOfModule,
        ...
    ]
})
export class AppModule {}

あるいは、16.0.0 以降、IgxForOfDirective をスタンドアロンの依存関係としてインポートできます。

// home.component.ts

import { IgxForOfDirective } from 'igniteui-angular/directives';
// 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 [];
}

Ignite UI for Angular ForOf モジュールまたはディレクティブをインポートしたので、igxFor ディレクティブの使用を開始できます。

Angular Virtual ForOf の使用

そのモジュールまたはディレクティブをインポートしたので、ローカル データにバインドする igxFor の基本構成を設定します。

<span #container>
    <ng-template *igxFor="data"></ng-template>
</span>

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>

注: 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>

水平仮想化および垂直仮想化

<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>

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>

注: igxForOf のインスタンスで totalItemCount プロパティを設定する必要があります。

this.virtDirRemote.totalItemCount = data['@odata.count'];

コンポーネントからディレクティブ インスタンスにアクセスするには、ViewChild としてマークします。

@ViewChild('virtDirRemote', { read: IgxForOfDirective })
public virtDirRemote: IgxForOfDirective<any>;

最初のチャンクをロードするリクエストの後、totalItemCount を設定できます:

public ngAfterViewInit() {
    this.remoteService.getData(this.virtDirRemote.state, (data) => {
        this.virtDirRemote.totalItemCount = data['@odata.count'];
    });
}

データをリクエストする際、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}`;
}

chunkPreload イベントが発生するたびに、新しいデータのチャンクをリクエストする必要があります。

chunkLoading(evt) {
    if(this.prevRequest){
        this.prevRequest.unsubscribe();
     }
     this.prevRequest = this.remoteService.getData(evt, ()=> {
        this.virtDirRemote.cdr.detectChanges();
    });
}

ローカル変数

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>

既知の制限

制限 説明
初期化後にレンダリングされたテンプレートのコンテンツのサイズが変更された場合、scrollTo メソッドが正しく動作しません。 テンプレート内の要素のサイズが初期化後に実行時に変化する場合 (コンテンツ プロジェクション、リモート要求の解決などの結果として)、scrollTo メソッドは正しいインデックスまでスクロールできません。メソッドは実行時のサイズ変更が発生する前のインデックスの位置までスクロールするため、後でサイズが変更されると位置が正しくなくなります。回避策として、コンテンツが後から読み込まれる場合は、コンテンツに応じてサイズが変わらないテンプレートを使用します。

API リファレンス

その他のリソース


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