Descripción general de la directiva ForOf virtual Angular

    La directiva Ignite UI for Angular igxForOf es una alternativa a ngForOf para crear plantillas para grandes cantidades de datos. Utiliza virtualización detrás de escena para optimizar la representación DOM y el consumo de memoria.

    Angular virtual para ejemplo de directiva

    EXAMPLE
    MODULES
    TS
    HTML
    SCSS

    ¿Te gusta esta muestra? Obtenga acceso a nuestro completo kit de herramientas Ignite UI for Angular y comience a crear sus propias aplicaciones en minutos. Descárgalo gratis.

    Primeros pasos con Ignite UI for Angular Virtual ForOf

    Para comenzar con la directiva igxFor Ignite UI for Angular, primero debe instalar Ignite UI for Angular. En una aplicación Angular existente, escriba el siguiente comando:

    ng add igniteui-angular
    cmd

    Para obtener una introducción completa a la Ignite UI for Angular, lea el tema de introducción.

    El siguiente paso es importar IgxForOfModule en su archivo 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 {}
    typescript

    Alternativamente, a partir de 16.0.0 puede importar IgxForOfDirective como una dependencia independiente.

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

    Ahora que ha importado la Ignite UI for Angular Tree Grid, puede comenzar a usar la directiva igxFor.

    Usando el ForOf virtual Angular

    Ahora que hemos importado el módulo o directiva, comencemos con una configuración básica de igxFor que se vincula a datos locales:

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

    La propiedad de datos es una matriz que proporciona los objetos de datos utilizados para construir el DOM virtualizado.

    Ejemplos

    La directiva igxFor se puede utilizar para virtualizar los datos en dirección vertical, horizontal o en ambas direcciones.

    La virtualización funciona de manera similar a la paginación al dividir los datos en bloques más pequeños que se intercambian desde una ventana gráfica de contenedor mientras el usuario desplaza los datos horizontal/verticalmente. La diferencia con el Paging es que la virtualización imita el comportamiento natural de la barra de desplazamiento. La directiva igxFor crea contenedores desplazables y representa pequeños fragmentos de datos. Se usa dentro de igxGrid y se puede usar para construir una igx-list virtual.

    Virtualización vertical

    <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

    Nota: Se recomienda encarecidamente que el contenedor principal de la plantilla igxForOf tenga aplicadas las siguientes reglas CSS: height para vertical y width para horizontal, overflow: hidden y position: relative. Esto se debe a que el comportamiento de desplazamiento suave se logra mediante desplazamientos de contenido que podrían afectar visualmente otras partes de la página si permanecen visibles.

    Virtualización horizontal

    <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

    EXAMPLE
    MODULES
    TS
    HTML
    SCSS

    Virtualización horizontal y vertical

    <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

    La directiva igxFor se utiliza para virtualizar datos en dirección vertical y horizontal dentro de igxGrid.

    Siga el tema Virtualización de Grid para obtener información y demostraciones más detalladas.

    igxPara vinculado al servicio remoto

    La directiva igxForOf se puede vincular a un servicio remoto utilizando la propiedad Observable-remoteData (en el siguiente caso). El evento chunkLoading también debe utilizarse para activar las solicitudes de datos.

    <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

    Nota: Es necesario establecer la propiedad totalItemCount en la instancia de igxForOf.

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

    Para acceder a la instancia de directiva desde el componente, se debe marcar como ViewChild:

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

    Después de la solicitud para cargar el primer fragmento, se puede configurar totalItemCount:

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

    Al solicitar datos, puede aprovechar la IgxForOfState interfaz, que proporciona las startIndex propiedades y chunkSize. Tenga en cuenta que inicialmente el chunkSize será 0, por lo que debe especificar el tamaño del primer fragmento cargado (el mejor valor es el inicial igxForContainerSize dividido por el 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

    Cada vez que se lanza el evento chunkPreload, se debe solicitar un nuevo fragmento de datos:

    chunkLoading(evt) {
        if(this.prevRequest){
            this.prevRequest.unsubscribe();
         }
         this.prevRequest = this.remoteService.getData(evt, ()=> {
            this.virtDirRemote.cdr.detectChanges();
        });
    }
    typescript
    App Builder | Banner de llamada a la acción

    Variables locales

    La directiva igxFor incluye las siguientes propiedades auxiliares en su contexto: even, odd, first y last. Se utilizan para identificar la posición actual del elemento en la colección. El siguiente fragmento de código demuestra cómo utilizar la propiedad even en una ng-template. Se asignará una clase even a cada elemento div par:

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

    Limitaciones conocidas

    Limitación Descripción
    scrollToEl método no funciona correctamente cuando el tamaño del contenido de las plantillas renderizadas cambia después de la inicialización. Cuando los elementos dentro de la plantilla tienen un tamaño que cambia el tiempo de ejecución después de la inicialización (por ejemplo, como resultado de la proyección de contenido, la resolución remota de solicitudes, etc.), entonces elscrollTo El método no podrá desplazarse al índice correcto. El método se desplazará a la posición del índice antes de que se produzca el cambio de tamaño en tiempo de ejecución, por lo que la ubicación no será correcta después de que se cambie el tamaño más adelante. Una posible solución es utilizar plantillas que no cambien su tamaño según su contenido si el contenido se carga más tarde.

    Referencias de API

    Recursos adicionales

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