前言
有時候需要根據URL來渲染不同組件,我所指的是在同一個URL地址中根據參數的變化顯示不同的組件;這是利用Angular動態加載組件完成的,同時也會設法讓這部分動態組件也支持AOT。
動態加載組件
下面以一個Step組件為示例,完成一個3個步驟的示例展示,并且可以通過URL user?step=step-one 的變化顯示第N個步驟的內容。
1、resolveComponentFactory
首先,還是需要先創建動態加載組件模塊。
import { Component, Input, ViewContainerRef, ComponentFactoryResolver, OnDestroy, ComponentRef } from '@angular/core';@Component({ selector: 'step', template: ``})export class Step implements OnDestroy { private currentComponent: ComponentRef<any>; constructor(private vcr: ViewContainerRef, private cfr: ComponentFactoryResolver) {} @Input() set data(data: { component: any, inputs?: { [key: string]: any } } ) { const compFactory = this.cfr.resolveComponentFactory(data.component); const component = this.vcr.createComponent(compFactory); if (data.inputs) { for (let key in data.inputs) { component.instance[key] = data.inputs[key]; } } this.destroy(); this.currentComponent = component; } destroy() { if (this.currentComponent) { this.currentComponent.destroy(); this.currentComponent = null; } } ngOnDestroy(): void { this.destroy(); }}拋開一銷毀動作不談的話,實際就兩行代碼:
let compFactory = this.cfr.resolveComponentFactory(this.comp);
利用 ComponentFactoryResolver 查找提供組件的 ComponentFactory,而后利用這個工廠來創建實際的組件。
this.compInstance = this.vcr.createComponent(compFactory);
這一切都非常簡單。
而對于一些基本的參數,是直接對組件實例進行賦值。
for (let key in data.inputs) { component.instance[key] = data.inputs[key]; }最后,還需要告訴Angular AOT編譯器為用戶動態組件提供工廠注冊,否則 ComponentFactoryResolver 會找不到它們,最簡單就是利用 NgModule.entryComponents 進行注冊。
@NgModule({ entryComponents: [ UserOneComponent, UserTwoComponent, UserThirdComponent ]})export class AppModule { }但這樣其實還是挺奇怪的,entryComponents 本身可能還會存在其他組件。而動態加載組件本身是一個通用性非常強,因此,把它封裝成名曰 StepModule 挺有必要的,這樣的話,就可以創建一種看起來更舒服的方式。
@NgModule({ declarations: [ Step ], exports: [ Step ]})export class StepModule { static withComponents(components: any) { return { ngModule: StepModule, providers: [ { provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: components, multi: true } ] } }}通過利用 ANALYZE_FOR_ENTRY_COMPONENTS 將多個組件以更友好的方式動態注冊至 entryComponents。
新聞熱點
疑難解答
圖片精選