Raúl Jiménez
elecash@gmail.com
@elecash
Angular GDE
videogular
academy partner
toptal partner
@Component({
selector: 'app-cfr-demo',
templateUrl: './cfr-demo.component.html',
styleUrls: [ './cfr-demo.component.scss' ],
encapsulation: ViewEncapsulation.None
})
export class CfrDemoComponent {
@ViewChild('placeholder', { read: ViewContainerRef }) viewContainerRef;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
addItem(type: string) {
const clazz = ViewOneComponent;
const factory = this.componentFactoryResolver.resolveComponentFactory(clazz);
const component = this.viewContainerRef.createComponent(factory);
}
}
Con component factory resolver podemos crear componentes al vuelo
<button (click)="addItem('one')">Add View One</button>
<button (click)="addItem('two')">Add View Two</button>
<ng-template #placeholder></ng-template>
Añadimos el ng-template donde instanciar el objeto creado dinámicamente
@Component({
selector: 'app-cfr-demo',
templateUrl: './cfr-demo.component.html',
styleUrls: [ './cfr-demo.component.scss' ],
encapsulation: ViewEncapsulation.None
})
export class CfrDemoComponent {
@ViewChild('placeholder', { read: ViewContainerRef }) viewContainerRef;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
addItem(type: string) {
const clazz = ViewOneComponent;
const factory = this.componentFactoryResolver.resolveComponentFactory(clazz);
const component = this.viewContainerRef.createComponent(factory);
(component.instance as IView).customMessage = 'my custom message';
}
}
También podemos pasar parámetros y modificar propiedades de nuestro objeto
Con template outlet podemos modificar templates internos de otro componente
<app-custom-list [items]="items">
<ng-template let-item="item">
<h2 class="red">{{ item.title }}</h2>
<strong>{{ item.speaker }}</strong>
</ng-template>
</app-custom-list>
En nuestro componente hijo recogemos la referencia del template en el padre con TemplateRef
@Component({
selector: 'app-custom-list',
templateUrl: './custom-list.component.html',
styleUrls: [ './custom-list.component.scss' ],
encapsulation: ViewEncapsulation.None
})
export class CustomListComponent {
@Input() items: Array<IItem> = [];
@ContentChild(TemplateRef) renderer;
constructor() {}
}
Y ya podemos instanciar ese template en el hijo conservando las referencias con ngTemplateOutletContext
<ul>
<li *ngFor="let item of items">
<ng-template [ngTemplateOutlet]="renderer"
[ngTemplateOutletContext]="{item: item}">
</ng-template>
</li>
</ul>