In this post, we are going to create our own structure directive *ngFor.
What it should looks like in HTML?
<div> <ul> <li *myFor="let item of items; let i = index;"> {{ i }} Member: {{ item.name | json }} </li> <template myFor [myForOf]="items" let-item let-i="index"> <li>{{ i }} Member: {{ item.name | json }}</li> </template> </ul> </div>
So here, we have a '*myFor' directive. It also use 'myForOf' direcitve. And a implicit value 'item'.
Notice that:
<li *myFor="let item of items; let i = index;"> {{ i }} Member: {{ item.name | json }} </li>
and
<template myFor [myForOf]="items" let-item let-i="index"> <li>{{ i }} Member: {{ item.name | json }}</li> </template>
They have the same effect.
Now let's create myFor directive:
import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core'; @Directive({ selector: '[myFor][myForOf]' }) export class MyForDirective { @Input() set myForOf(collection) { this.view.clear(); collection.forEach((item, index) => { this.view.createEmbeddedView( this.template, { $implicit: item, index } ) }); } constructor( private view: ViewContainerRef, private template: TemplateRef<any> ) { // this.template will point to the host element } }
It is good to clear the view every time we generate new embedded view:
this.view.clear();
Also we gave implicit 'value' and 'index'.
this.view.createEmbeddedView( this.template, { $implicit: item, // let-item index // let-i="index" } )