前言
一個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層,當提交的時候統一傳送給後臺。
感謝宇軒同學提供的幫助。