编辑:这是我的Stackblitz应用程序的Editor url,它以简化的设置显示了第一个控件和第二个控件之间的值"转移"问题.
我正在处理一个Angular 动态的表单,其中表单 struct 会根据用户输入进行更改.表单中的每个问题都由FormGroup中的唯一控件表示,这些控件在用户浏览问题时动态创建或更新.我的方法包括更新CurrentControlName并在导航时重新创建表单控件(使用nextPage和PrevessPage方法),以确保每个问题在表单中都有自己的唯一控件.
方法:
我使用服务来获取基于所选服务的问题. 表单在ngOnInit中初始化,第一个问题作为当前问题. 在问题之间导航时,我 for each 问题创建一个新的FormControl,使用问题ID通过唯一的名称进行标识. 我将响应存储在一个对象中,以便即使在问题之间来回导航时也能维护答案.
问题:
在输入第一个问题的回答并导航到第二个问题后,第二个问题的输入字段错误地显示为第一个问题输入的值.此外,更新第二个问题的值不会触发预期的valueChanges observable,而且表单控件和模板之间似乎存在不匹配或绑定问题.
具体地说,就是:
第一个输入控件按预期工作,记录值更改. 在导航到第二个问题并更新其控件之后,没有记录任何更改,这表明可能没有为新创建的控件正确设置Observable. 尽管在每个导航上重新创建了表单组和控件,但模板中控件值的绑定似乎一直存在问题.
try 解决以下问题:
已确保根据问题ID for each FormControl提供唯一的名称. Used valueChanges可观察以记录和跟踪控件值的更改. 在每次导航时重新创建FormGroup及其控件,以try 并重置窗体状态.
我正在寻找洞察力或解决方案,以确保每个动态创建的控件正确地反映其在模板中的值,并且准确地检测和记录值更改.任何关于如何解决绑定问题或改进Angular 的动态表单处理的建议都将不胜感激.
Angular CLI:14.2.4 node :21.6.1
编辑:重现我的问题的极简主义代码
Minimal.component.ts
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
interface Question {
id: string;
label: string;
}
@Component({
selector: 'app-minimal-form',
templateUrl: './Minimal.component.html',
})
export class MinimalFormComponent implements OnInit {
myForm: FormGroup;
currentQuestion: Question;
questions: Question[] = [
{ id: 'A', label: 'Question A' },
{ id: 'B', label: 'Question B' },
];
currentControlName: string;
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.currentQuestion = this.questions[0];
this.currentControlName = `question_${this.currentQuestion.id}`;
this.myForm = this.fb.group({
[this.currentControlName]: ['', Validators.required],
});
}
goToNextQuestion(): void {
const currentIndex = this.questions.findIndex(q => q.id === this.currentQuestion.id);
const nextIndex = currentIndex + 1;
if (nextIndex < this.questions.length) {
this.currentQuestion = this.questions[nextIndex];
this.currentControlName = `question_${this.currentQuestion.id}`;
this.myForm = this.fb.group({
[this.currentControlName]: ['', Validators.required],
});
}
}
}
Minimal.component.html
<form [formGroup]="myForm">
<label>{{ currentQuestion.label }}</label>
<input type="text" [formControlName]="currentControlName">
<button type="button" (click)="goToNextQuestion()">Next Question</button>
</form>