如果是单页面应用程序, 页面的模板不可能是一成不变的, 因为它在运行时会动态地加载一些新的组件。 此时,就需要动态组件加载器。
如何生成动态组件? 有以下几步:
1. 准备好要显示的组件: AComponent, BComponent,… XComponent
比如创建一个基础组件AComponent。
import { Component, Input } from '@angular/core';
@Component({
template: `
<div class="xx-container">
<h4>{{data.headline}}</h4>
{{data.body}}
</div>
`
})
export class XXComponent {
@Input() data: any;
}
2. 用一个service返回需要的组件以及对应的数据: getXXservice()
比如返回A组件和B组件以及需要传入的数据。
import { Injectable } from '@angular/core';
import { AComponent } from './a.component';
import { BComponent } from './b.component';
import { XItem } from './X-item';
@Injectable()
export class XXService {
getAds() {
return [
new XItem(AComponent, {name: 'This is name', bio: 'This is bio'}),
new XItem(BComponent, {headline: 'This is headline', body: 'This is body'})
];
}
}
这里, 定义了一个XItem的类型并导出供使用。
import { Type } from '@angular/core';
export class XItem {
constructor(public component: Type<any>, public data: any) {}
}
3. 拿到动态组件的插入点以及该点的视图访问权: ViewContainerRef
根据angular官网介绍, 此时我们需要知道要把这些动态组件插入到哪里。 此时就需要定义一个锚点告诉Angular要把组件插入到什么地方。用指令实现。
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[xxHost]',
})
export class XxDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
ViewContainerRef
表示可以将一个或多个视图附着到组件中的容器。
<ng-template xxHost></ng-template>
ng-template
元素不会渲染额外输出,可用来加载动态组件。
4. 创建组件: componentFactoryResolver
componentFactoryResolver
是一个简单的注册表, 它将组件映射到生成的componentFactory类, 该类可以用于创建组件的实例。
const viewContainerRef = this.xxHost.viewContainerRef; //获取该锚点的视图访问权
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(XXComponent); //注册组件
const componentRef = viewContainerRef.createComponent(componentFactory); //创建组件
componentRef.instance.data = XxItem.data; //绑定数据
以上四步就可以实现一个小小的动态组件加载器了!
如果是企业级项目,也万变不离其宗。