Angular 14:表单组件工厂模式实现异常问题
Angular中表单工厂模式的实现问题
我想在Angular中实现工厂模式,用来创建多个具有不同属性的表单,因此打算构建一个表单工厂,根据传入的类型渲染对应的表单。
现有代码
app.component.html
<app-form-builder [type]="'phoneForm'"></app-form-builder>
form-builder.component.ts
interface FormMapping { [key: string]: ComponentRef<FormNameComponent | FormPhoneComponent>; } @Input() type: string = ''; constructor(public viewContainerRef: ViewContainerRef) {} getFormTypes(type: string) { const formMapping: FormMapping = { nameForm: this.viewContainerRef.createComponent(FormNameComponent), phoneForm: this.viewContainerRef.createComponent(FormPhoneComponent), }; formMapping[type]; } ngOnInit(): void { this.getFormTypes(this.type); }
表单组件的具体实现无关紧要:phoneForm是带input type="number"的表单,nameForm是带input type="text"的表单。
遇到的问题
使用多分支if判断的方式可以正常工作,只会渲染对应类型的表单:
getFormType(type: string) { if (type === 'nameForm') { this.viewContainerRef.createComponent(FormNameComponent); } if (type === 'phoneForm') { this.viewContainerRef.createComponent(FormPhoneComponent); } }
但用对象映射的方式会同时渲染两个表单,不清楚原因。
问题原因
对象映射的写法中,构建formMapping对象时,会立即执行两个createComponent方法调用——不管你后续是否使用对应的属性,这两个组件都会被实例化并添加到视图容器中,所以会同时渲染。而if判断的写法只会根据传入的type执行对应的创建逻辑,因此只会渲染一个表单。
修正方案
把组件类本身存储在映射对象中,而不是直接调用createComponent,在确定需要的类型后再执行创建操作:
// 修改映射接口,存储组件类类型 interface FormMapping { [key: string]: typeof FormNameComponent | typeof FormPhoneComponent; } getFormTypes(type: string) { // 先清空容器,避免重复渲染 this.viewContainerRef.clear(); const formMapping: FormMapping = { nameForm: FormNameComponent, phoneForm: FormPhoneComponent, }; const TargetFormComponent = formMapping[type]; if (TargetFormComponent) { this.viewContainerRef.createComponent(TargetFormComponent); } }
额外建议:每次创建组件前调用viewContainerRef.clear(),可以清空容器内已有的组件,防止多次切换类型时出现叠加渲染的问题。
内容的提问来源于stack exchange,提问作者jgcarrillo
相关产品推荐
相关产品推荐

