foreword
There are always various problems when a demo is applied to a project.
version problem
When writing the project, I wrote according to the experimental demo a few days ago, viemContainerRef.createComponent<A>(B)
, B is the implementation class of the A interface, but here B reports an error. I didn't read the error details carefully at first, thinking it was the inheritance relationship between B and A. There is a problem, but after checking it is not wrong. After searching online, I couldn't find a solution. Then I went to check the source code,
I found that the method parameter needs a factory class instead of a subclass, and I was puzzled. Why is there no problem in the demo. Go to the demo and look at the source code.
It is found that the parameter types are not the same, and it is found that it is an angular version problem. The project uses the angular12 version, while the demo uses the angular13 version. The final cause is a version problem.
Go to Google's example of use of viemContainerRef.createComponent(), the old version is still used on the Internet, and write it down
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;
}
Later, I went to the official website of the old version of angular and found a similar way of writing.
Citation problem
@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;
}
Encountered an undefined problem. At this time, formItem
was injected using the @ViewChild annotation. There is no error message, so I can only guess. In order to prevent version problems, I also checked the official code and source code of version 12, and there was no problem.
In the official example, the instruction and the component are in the same module, and they are not injected through the @ViewChild annotation. I guess it may be because the instruction is not introduced, and the instruction and the component are in different modules. I try to put the two into the agreed module, which has been excluded and is not a reference. error, did not solve the problem.
For a while, I ran out of ideas, and with the help of Yuxuan, I found the problem.
The solution is to introduce ViewModule
into TaskModule
, ViewModule
is the module where the component where the instruction is located, and TaskModule
is the total module of the large function module.
├── add
├── directive
├── edit
├── form-item-type
├── index
├── item-add
├── item-edit
├── item-view
├── task-routing.module.ts
├── task.module.ts
└── view
But why it is enough to change this, neither of us want to understand.
some other questions
In a dynamic form, the array of form items returned by the background must not be stored in a component, and the front desk needs to dynamically load the components corresponding to each form item type. If you simply write an if statement to judge one by one, using a dynamic form will become It was useless, I thought that I could use the HashMap data structure to store the form item type and the corresponding component, and get the component corresponding to the form item type when I used it.
Form pass-by-value is also a problem, unlike the traditional v-layer that lists each single item together. The idea is to pass each form value to the m layer first, and send it to the background uniformly when it is submitted.
Thank you Yuxuan for your help.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。