Angular Resumen virtual de la directiva ForOf
La directiva igxForOf Ignite UI for Angular es una alternativa a ngForOf para crear plantillas de grandes cantidades de datos. Utiliza la virtualización en segundo plano para optimizar el renderizado del DOM y el consumo de memoria.
Angular Virtual For Directive Example
Getting Started with Ignite UI for Angular Virtual ForOf Directive
To get started with the Ignite UI for Angular igxFor directive, first you need to install Ignite UI for Angular. In an existing Angular application, type the following command:
ng add igniteui-angular
Para obtener una introducción completa al Ignite UI for Angular, lea el tema de introducción.
El siguiente paso es importarlosIgxForOfModule en tu archivo app.module.ts.
// app.module.ts
import { IgxForOfModule } from 'igniteui-angular/directives';
// import { IgxForOfModule } from '@infragistics/igniteui-angular'; for licensed package
@NgModule({
imports: [
...
IgxForOfModule,
...
]
})
export class AppModule {}
Alternativamente,16.0.0 puedes importarlosIgxForOfDirective como una dependencia independiente.
// 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 [];
}
Now that you have the Ignite UI for Angular Tree Grid module or directives imported, you can start using the igxFor directive.
Using the Angular Virtual ForOf
Now that we have the module or directive imported, let’s get started with a basic configuration of the igxFor that binds to local data:
<span #container>
<ng-template *igxFor="data"></ng-template>
</span>
La propiedad de datos es una matriz que proporciona los objetos de datos utilizados para construir el DOM virtualizado.
Examples
The igxFor directive can be used to virtualize the data in vertical, horizontal or both directions.
Virtualization works similarly to Paging by slicing the data into smaller chucks which are swapped from a container viewport while the user scrolls the data horizontally/vertically. The difference with the Paging is that virtualization mimics the natural behavior of the scrollbar. The igxFor directive is creating scrollable containers and renders small chunks of the data. It is used inside the igxGrid and it can be used to build a virtual igx-list.
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>
Note: It is strongly advised that the parent container of the igxForOf template has the following CSS rules applied: height for vertical and width for horizontal, overflow: hidden and position: relative. This is because the smooth scrolling behavior is achieved through content offsets that could visually affect other parts of the page if they remain visible.
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>
The igxFor directive is used to virtualize data in both vertical and horizontal directions inside the igxGrid.
Siga el tema Virtualización de Grid para obtener información y demostraciones más detalladas.
igxFor bound to remote service
The igxForOf directive can be bound to a remote service using the Observable property - remoteData (in the following case). The chunkLoading event should also be utilized to trigger the requests for data.
<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>
Note: There is a requirement to set the totalItemCount property in the instance of igxForOf.
this.virtDirRemote.totalItemCount = data['@odata.count'];
In order to access the directive instance from the component, it should be marked as ViewChild:
@ViewChild('virtDirRemote', { read: IgxForOfDirective })
public virtDirRemote: IgxForOfDirective<any>;
After the request for loading the first chunk, the totalItemCount can be set:
public ngAfterViewInit() {
this.remoteService.getData(this.virtDirRemote.state, (data) => {
this.virtDirRemote.totalItemCount = data['@odata.count'];
});
}
When requesting data you can take advantage of the IgxForOfState interface, which provides the startIndex and chunkSize properties. Note that initially the chunkSize will be 0, so you have to specify the size of the first loaded chunk (the best value is the initial igxForContainerSize divided by the 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}`;
}
Every time the chunkPreload event is thrown, a new chunk of data should be requested:
chunkLoading(evt) {
if(this.prevRequest){
this.prevRequest.unsubscribe();
}
this.prevRequest = this.remoteService.getData(evt, ()=> {
this.virtDirRemote.cdr.detectChanges();
});
}
Local Variables
The igxFor directive includes the following helper properties in its context: even, odd, first and last. They are used to identify the current element position in the collection. The following code snippet demonstrates how to use the even property in an ng-template. Аn even class will be assigned to every even div element:
<ng-template igxFor let-item let-isEven="even"
[igxForOf]="data"
[igxForScrollOrientation]="'vertical'" >
<div [ngClass]="{even: isEven}"></div>
</ng-template>
Known Limitations
| 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. |