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" } )