前言
一个 demo 利用到我的项目上的时候总会呈现各种各样的问题。
版本问题
在编写我的项目时,照着前几天的试验 demo 写,viemContainerRef.createComponent<A>(B)
,B 是 A 接口的实现类,然而在这里 B 却报错了,一开始没认真看报错详细信息,认为是 B 对 A 的继承关系有问题,然而查看了后并没有错。去网上找了一番后也没有发现解决办法。而后我去查看源码,
发现办法参数须要一个工厂类而不是一个子类,感到了纳闷,怎么 demo 里没问题呢。又去 demo 里看了一下源码。
发现参数类型并不相同,发现是 angular 版本问题,我的项目用的是 angular12 版本,而 demo 用的是 angular13 版本。最终起因是版本问题造成的。
去谷歌 viemContainerRef.createComponent()的应用实例,网上还是老版本的应用,照着写上
constructor(private resolver: ComponentFactoryResolver) {}
loadComponent() {const factory: ComponentFactory<FormItemTypeComponent> = this.resolver.resolveComponentFactory(FormItemTextComponent);
const viewContainerRef = this.formItem.viewContainerRef;
const componentRef = viewContainerRef.createComponent(factory);
componentRef.instance.formItem = formItem;}
起初又去了的老版本的 angular 官网,也发现了相似的写法。
援用问题
@ViewChild(FormItemDirective, {static: true})
formItem!: FormItemDirective;
loadComponent() {for (var i = 0; i < this.task.formItems.length; i++) {const formItem = this.task.formItems[i];
console.log(this.formItem);
const factory: ComponentFactory<FormItemTypeComponent> =
this.resolver.resolveComponentFactory(FormItemTextComponent);
const viewContainerRef = this.formItem.viewContainerRef;
const componentRef = viewContainerRef.createComponent(factory);
componentRef.instance.formItem = formItem;
}
遇到一个 undefined 问题,此时的 formItem
是应用 @ViewChild 注解注入进来的,这个也没有什么报错信息,只能猜了。为了避免版本问题,我也查看了 12 版本的官网代码和源码,并没有什么问题。
官网实例里指令跟组件在一个模块里,没有通过 @ViewChild 注解注入进来,猜想可能是因为没有引入指令,而指令跟组件在不同的模块里,我尝试将两者放入批准模块已排除不是援用的谬误,也没有解决问题。
一时没有了思路,在宇轩同学的帮忙下,找到了问题所在。
解决办法是将 ViewModule
引入 TaskModule
中,ViewModule
是指令所在组件的所在模块,TaskModule
是大功能模块的总模块。
├── add
├── directive
├── edit
├── form-item-type
├── index
├── item-add
├── item-edit
├── item-view
├── task-routing.module.ts
├── task.module.ts
└── view
然而为什么改这个就能够了,我俩都没有想明确。
其余一些问题
在动静表单里,后盾返回的表单项数组必然不可能存入一个组件进去,而前台须要每个表单项类型所对应组件动静加载,如果单纯的写 if 语句进行挨个判断,应用动静表单又成了无用功,想到能够应用 HashMap 数据结构,将表单项类型与对应组件存储起来,用的时候获取表单项类型所对应组件。
表单传值也是一个问题,不同于传统的 v 层将每个标单项列举在一起。想法是通过将每个表单值先传到 m 层,当提交的时候对立发送给后盾。
感激宇轩同学提供的帮忙。