问题
I use template driven and am trying to initialize my form using patchValue and it is not working.
I can make it work if I use two-way binding to set values [(fooBar)] or even setTimeout but I was just wondering, is there a way to make it work with just patchValue?
https://stackblitz.com/edit/angular-fft2c5
Thank you.
回答1:
It doesn't work because at the time of calling patchValue method there are no any controls registered in your form yet.
Why?
That's because Template-driven forms are asynchronous. They delegate creation of their form controls to directives. To avoid "changed after checked" errors, these directives take more than one cycle to build the entire control tree. That means you must wait a tick before manipulating any of the controls from within the component class.
Moreover, if you try using setValue method instead of patchValue Angular will even warn you how to deal with it.
this.myForm.control.setValue({name: this.name});
ERROR Error: There are no form controls registered with this group yet. If you're using ngModel, you may want to check next tick (e.g. use setTimeout).
So, as you already discovered, you have to either use [ngModel] binding or wait next tick by using e.g setTimeout or requestAnimationFrame
Scheduling microtask should also work if you would use it in ngAfterViewInit hook:
ngAfterViewInit() {
Promise.resolve().then(() => {
this.myForm.control.patchValue({ name: this.name });
});
}
回答2:
In template driven forms, you need to bind [(ngModel] to set values.
Try like this:
.html
<input name="name" [(ngModel)]="formValue.name"/>
.ts
formValue:any = {}
ngOnInit() {
this.formValue = {name: this.name}
}
Working Demo
来源:https://stackoverflow.com/questions/59674775/initialize-using-patchvalue-for-template-driven-forms