Angular Dynamic Component ComponentFactoryResolver
▌Introduction
We will update our Component-Outlet directive and make it support passing parameter to the component.
▋Related articles
▌Environment
▋Angular 2.1.0
▌Implement
▋Update Component Outlet
Add a new input property: inputValue,
to the ComponentOutlet.
▋component-oulet.directive.ts
import { Directive, Component, ComponentFactory,
OnChanges, Input, ViewContainerRef, Compiler, ComponentFactoryResolver } from '@angular/core';
@Directive({
selector: '[component-outlet]'
})
export class ComponentOutlet implements OnChanges {
@Input()
selector: string;
@Input() inputValue: any;
componentRef;
constructor(
private vcRef:
ViewContainerRef,
private resolver:
ComponentFactoryResolver) {
}
ngOnChanges()
{
if (!this.selector) return;
const factories =
Array.from(this.resolver['_factories'].values());
const factory: any =
factories.find((x: any) => x.selector === this.selector);
const compRef:any = this.vcRef.createComponent(factory);
//Set input value for the component (optional)
compRef.instance.inputValue = this.inputValue;
if (this.componentRef) {
this.componentRef.destroy();
}
this.componentRef =
compRef;
}
public ngOnDestroy() {
if (this.componentRef) {
this.componentRef.destroy();
this.componentRef = null;
}
}
}
|
▋Usage
Let’s
update the previous sample that users can choose the style for showing the
customers’ data and HOW MANY records should be displayed.
▋app.component.ts
<!-- New -->
<div class="col-sm-3"><input type="text" class="form-control" [(ngModel)]="maxDisplayNum" value="" /></div>
<!-- Update -->
<div component-outlet [selector]="component" [inputValue]="maxDisplayNum"></div>
|
Okay, we can pass a parameter
to the Component-Outlet and it’s time to update the target components.
Take “List style” component
for example,
▋list.component.ts
import {Component, OnInit,
Input} from '@angular/core';
import {Customer} from '../../../class/Customer';
import {CustomerService} from '../../../service/customer.service';
import {RestUriService} from '../../../service/resturi.service';
@Component({
selector: 'customerdynamic-list',
providers:
[CustomerService, RestUriService],
templateUrl: '/app/component/Basic/CustomerDynamic/list.component.html'
})
export class
CustomerDynamicListComponent implements OnInit {
@Input() inputValue: number;
customers:
Customer[];
constructor(private custService:
CustomerService) {
}
ngOnInit() {
this.initCustomers();
}
private initCustomers() {
this.custService.getAll().then(
data => {
this.customers = [];
if (!this.inputValue) {
this.customers = data
}
else {
for (let i = 0; i < this.inputValue; i++) {
this.customers.push(data[i]);
}
}
});
}
}
|
▋Demo
▌Github
▌Reference
沒有留言:
張貼留言