来自angular官网个人学习笔记
🌰 轮播图的动态加载案例
添加指令
编写组件之前,自定义一个指令AdDirective告诉angular这个组件的插入位置
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[adHost]',
})
export class AdDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
ViewContainerRef用于获取需要动态添加component的视图容器
@Directive 指令使选择器修饰adHost,用于申请指令到element中。
指令使用到组件上
<ng-template> 可以很好的使用刚才定义的指令生成动态组件,因为它没有渲染出任何额外的组件.
为了发出一个AdDirective, 我们从 ad.directive.ts中调用[adHost]指令, 去掉方括号就可以在 <ng-template>中使用。
//ad-banner.component.ts
template: `
<div class="ad-banner-example">
<h3>Advertisements</h3>
<ng-template adHost></ng-template>
</div>
`
动态加载的具体实现
所注入的参数AdItem将最终来自请求的轮播数据。让我们的AdBannerComponent能够被动态渲染。
getAds()方法每三秒调用一次loadComponent()。来每次加载一些AdItems数组的新组件。
//ad-banner.component.ts
export class AdBannerComponent implements OnInit, OnDestroy {
@Input() ads: AdItem[] = [];
currentAdIndex = -1;
@ViewChild(AdDirective, {static: true}) adHost!: AdDirective;
interval: number|undefined;
ngOnInit(): void {
this.loadComponent();
this.getAds();
}
ngOnDestroy() {
clearInterval(this.interval);
}
loadComponent() {
//将 currentAdIndex 设为目前的值+1,除以AdItem的长度来赋给 currentAdIndex
//之后再使用这个值去从数组里选择一个adItem
this.currentAdIndex = (this.currentAdIndex + 1) % this.ads.length;
const adItem = this.ads[this.currentAdIndex];
//`AdDirective`注入`ViewContainerRef`到它的构造函数中。这就是指令访问您要用于托管动态组件的元素的方式。
//要将组件添加到模板中,请调用ViewContainerRef.createComponent
const viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent<AdComponent>(adItem.component);
componentRef.instance.data = adItem.data;
}
getAds() {
this.interval = setInterval(() => {
this.loadComponent();
}, 3000);
}
}