Visão geral da diretiva Angular Virtual ForOf

    A diretiva igxForOf Ignite UI for Angular é uma alternativa ao ngForOf para criar modelos de grandes quantidades de dados. Ela usa virtualização nos bastidores para otimizar a renderização do DOM e o consumo de memória.

    Angular Virtual For Directive Example

    Getting Started with Ignite UI for Angular Virtual ForOf Directive

    Para começar a usar a diretiva igxFor Ignite UI for Angular, primeiro você precisa instalar Ignite UI for Angular. Em um aplicativo Angular existente, digite o seguinte comando:

    ng add igniteui-angular
    

    Para obter uma introdução completa ao Ignite UI for Angular, leia o tópico de introdução.

    O próximo passo é importar o IgxForOfModule no seu arquivo app.module.ts.

    // app.module.ts
    
    import { IgxForOfModule } from 'igniteui-angular';
    // import { IgxForOfModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        imports: [
            ...
            IgxForOfModule,
            ...
        ]
    })
    export class AppModule {}
    

    Como alternativa, a partir da 16.0.0 você pode importar o IgxForOfDirective como uma dependência autônoma.

    // 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 [];
    }
    

    Agora que você importou o módulo Ignite UI for Angular Tree Grid ou as diretivas, você pode começar a usar a diretiva igxFor.

    Using the Angular Virtual ForOf

    Agora que importamos o módulo ou diretiva, vamos começar com uma configuração básica do igxFor que se vincula aos dados locais:

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

    A propriedade de dados é uma matriz que fornece os objetos de dados usados para construir o DOM virtualizado.

    Examples

    A diretiva igxFor pode ser usada para virtualizar os dados na vertical, na horizontal ou em ambas as direções.

    A virtualização funciona de forma semelhante ao Paging, cortando os dados em pedaços menores que são trocados de uma viewport de contêiner enquanto o usuário rola os dados horizontalmente/verticalmente. A diferença com o Paging é que a virtualização imita o comportamento natural da barra de rolagem. A diretiva igxFor está criando contêineres roláveis e renderiza pequenos pedaços dos dados. Ela é usada dentro do igxGrid e pode ser usada para construir uma igx-list virtual.

    Vertical virtualization

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

    Nota: É altamente recomendável que o contêiner pai do modelo igxForOf tenha as seguintes regras CSS aplicadas: height para vertical e width para horizontal, overflow: hidden e position: relative. Isso ocorre porque o comportamento de rolagem suave é obtido por meio de deslocamentos de conteúdo que podem afetar visualmente outras partes da página se permanecerem visíveis.

    Horizontal virtualization

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

    Horizontal and vertical virtualization

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

    A diretiva igxFor é usada para virtualizar dados nas direções vertical e horizontal dentro do igxGrid.

    Siga o tópico Virtualização de grade para obter informações e demonstrações mais detalhadas.

    igxFor bound to remote service

    A diretiva igxForOf pode ser vinculada a um serviço remoto usando a propriedade Observable-remoteData (no caso a seguir). O evento chunkLoading também deve ser utilizado para disparar as solicitações de dados.

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

    Observação: há um requisito para definir a propriedade totalItemCount na instância de igxForOf.

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

    Para acessar a instância da diretiva do componente, ela deve ser marcada como ViewChild:

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

    Após a solicitação de carregamento do primeiro bloco, o totalItemCount pode ser definido:

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

    Ao solicitar dados, você pode aproveitar a interface IgxForOfState, que fornece as propriedades startIndex e chunkSize. Observe que inicialmente o chunkSize será 0, então você tem que especificar o tamanho do primeiro chunk carregado (o melhor valor é o igxForContainerSize inicial dividido pelo 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}`;
    }
    

    Toda vez que o evento chunkPreload é lançado, um novo bloco de dados deve ser solicitado:

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

    Local Variables

    A diretiva igxFor inclui as seguintes propriedades auxiliares em seu contexto: even, odd, first e last. Elas são usadas para identificar a posição atual do elemento na coleção. O seguinte trecho de código demonstra como usar a propriedade even em um ng-template. Uma classe even será atribuída a cada elemento div even :

    <ng-template igxFor let-item let-isEven="even"
                 [igxForOf]="data" 
                 [igxForScrollOrientation]="'vertical'" >
        <div [ngClass]="{even: isEven}"></div>
    </ng-template>
    

    Known Limitations

    Limitação Descrição
    scrollToo método não funciona corretamente quando o tamanho do conteúdo dos modelos renderizados muda após a inicialização Quando os elementos dentro do modelo têm um tamanho que muda o tempo de execução após a inicialização (por exemplo, como resultado da projeção de conteúdo, resolução de solicitação remota etc.), então oscrollTo o método não conseguirá rolar para o índice correto. O método rolará para a posição do índice antes que a alteração do tamanho do tempo de execução ocorra, portanto, o local não estará correto depois que o tamanho for alterado posteriormente. Uma possível solução alternativa é usar modelos que não alterem seu tamanho com base em seu conteúdo se o conteúdo for carregado posteriormente.

    API References

    Additional Resources

    Our community is active and always welcoming to new ideas. * [Ignite UI for Angular **Forums**](https://pt-br.infragistics.com/community/forums/f/ignite-ui-for-angular) * [Ignite UI for Angular **GitHub**](https://github.com/IgniteUI/igniteui-angular)