angular动态组件加载器的个人理解
时间:2023-03-28 12:12:30
HTML
本文基于angular官方文档给出的代码。Portal我们以广告为例来演示其相应的功能。下面是我们要达到的效果:我们会发现广告有不同的尺寸和格式。同样的格式会有不同的内容。我们先来解释一下这是如何实现的。每种格式的广告对应一个组件,这些组件必须实现一个公共接口来向组件传递数据。我们例子中的接口很简单,只声明了数据项,我们在使用过程中还可以进行更详细的设置://广告组件实现的公共接口exportinterfaceAdComponent{data:any;}之后,我们可以如下使用把我们广告栏的样式写成这样:@Component({template:`{{data.headline}}
{{data.body}}
`})exportclassHeroJobAdComponentimplementsAdComponent{//接受传入的数据@Input()data:any;}之后我们需要指定整个广告的内容如下——声明源组件广告的格式和内容exportclassAdItem{constructor(publiccomponent:Type
,publicdata:any){}}之后我们就可以转入service层来编写广告的获取操作了:@Injectable()exportclassAdService{getAds(){return[newAdItem(HeroProfileComponent,{name:'Bombasto',bio:'Brave当他们来的时候'}),newAdItem(HeroProfileComponent,{name:'DrIQ',bio:'当他们来的时候聪明'}),...];}}然后是最重要的部分——动态组件加载器。在添加组件之前,必须定义一个锚点来告诉Angular在何处插入组件。使用名为AdDirective的辅助指令来标记模板中的有效插入点。@Directive({selector:'[adHost]',})exportclassAdDirective{constructor(publicviewContainerRef:ViewContainerRef){}}AdDirective注入ViewContainerRef获取容器视图的访问权限,也就是动态添加的组件Host。这里我个人的理解是:ViewContainerRef可以实现在当前组件中插入显示其他组件内容的功能。先放出动态组件加载器中的完整代码:exportclassAdBannerComponentimplementsOnInit,OnDestroycurrentAdIndex=-1;@ViewChild(AdDirective,{static:true})adHost!:AdDirective;间隔:数字|未定义;ngOnInit(){this.loadComponent();this.getAds();}ngOnDestroy(){clearInterval(this.interval);}loadComponent(){//当前广告,用于在广告数组中循环采样this.currentAdIndex=(this.currentAdIndex+1)%this.ads.length;constadItem=this.ads[this.currentAdIndex];constviewContainerRef=this.adHost.viewContainerRef;//清除当前视图的广告,避免广告堆积viewContainerRef.clear();constcomponentRef=viewContainerRef.createComponent(adItem.component);componentRef.instance.data=adItem.data;}getAds(){this.interval=setInterval(()=>{this.loadComponent();},3000);首先,我们使用@ViewChild注解从模板视图中获取匹配的元素,也就是获取我们上面配置的锚点。接下来,我们将viewContainerRef指向该组件的现有实例。loadComponent()方法在这里很重要。它首先选择一个广告。要将此组件添加到模板,我们在ViewContainerRef上调用createComponent()。createComponent()方法返回对刚刚加载的组件的引用。使用此引用与组件交互,例如设置其属性或调用其方法。也就是说,我们需要通过viewContainerRef和componentRef绑定要展示的广告的component,然后将广告的数据传递给componentRef.instance,而这个componentRef就是我们要展示的内容。之后我们要做的就是每隔一定时间周期性的调用loadComponent(),这里我们使用如下代码来实现:interval:number|undefined;ngOnInit(){this.loadComponent();this.getAds();}getAds(){this.interval=setInterval(()=>{this.loadComponent();},3000);}至此我们的动态组件加载器就完成了,我们只需要在页面中展示广告就可以这样调用://V层广告是通过上面的M层得到的。//c层this.ads=this.adService.getAds();流程图: