angular 动态组件加载器
动态加载组件用于需要在运行期间加载一些新的组件的场景。
angular自带的API支持动态加载组件。
- 锚点
在添加组件之前,需要先定义一个锚点来告诉angular把组件插入到什么地方。
Directive
将类标记为Angular指令的装饰器。通过这个指令可以定义自己的指令,以将自定义的行为附加到DOM
中的元素。它的子类是
Component
ViewContainerRef
表示可以将一个或多个视图附着到组件中的容器。可以包含宿主视图(当用createComponent()
方法实例化组件时创建)和内嵌视图(当用createEmbeddedView()
方法实例化 TemplateRef 时创建)
import { Directive,ViewContainerRef } from '@angular/core';
@Directive({
selector:'[adHost]'
})
export class AdDirective{
constructor(public viewContainerRef:ViewContainerRef){}
}
- 加载组件
ng-template
对应类TemplateRef
,表示一个内嵌模板,它可以用于实例化内嵌的视图。
<-- ad-banner.html --!>
<div>
<h3>Advertisements</h3>
<ng-template adHost></ng-template>
</div>
ng-template
是动态加载组件的最佳选择,因为它不会输出任何额外渲染。
@Component({
selector:'app-ad-banner',
templateUrl:'./ad-banner.html',
styleUrls:['./ad-banner.css']
})
export class AdBannerComponent implements OnInit,OnDestroy{
@Input() ads:AdItem[];
currentIndex = -1;
@viewchild(AdDirective,{static:true}) adHost:AdDirective;
interval:any;
constructor(private componentFactoryResolver:ComponentFactoryResolver){
}
ngOnInit(){
this.loadComponent();
this.getAds();
}
ngDestory(){
clearInterval(this.interval);
}
loadComponent(){
this.currentIndex = (this.currentIndex+1)%this.ads.length;
const adItem = this.ads[this.currentAdIndex];
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component); //创建类工厂
const viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear(); // 清除内容
const componentRef = viewContainerRef.createComponent<AdComponent>(componentFactory); // 为锚点创建组件
componentRef.instance.data = adItem.data; // 导入数据
}
}
- 被加载的组件
所有被加载的组件都需要实现一个公共接口,在官方文档中的公共接口为 AdComponent
,它定义了一个标准化的API来把数据传给组件。
export interface AdComponent {
data:any;
}
Comments | NOTHING