angular 动态组件加载器

发布于 2021-03-31  739 次阅读


angular 动态组件加载器

动态加载组件用于需要在运行期间加载一些新的组件的场景。
angular自带的API支持动态加载组件。

  1. 锚点
    在添加组件之前,需要先定义一个锚点来告诉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){}
}
  1. 加载组件

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; // 导入数据
    }
}
  1. 被加载的组件

所有被加载的组件都需要实现一个公共接口,在官方文档中的公共接口为 AdComponent,它定义了一个标准化的API来把数据传给组件。

export interface AdComponent {
    data:any;
}

朝闻道,夕死可矣