我是Angular的新手,无法弄清楚使用异步调用更新反应式表单。
我有一个基于对象模型的反应形式。表单中的任何更改都会触发HTTP请求,该HTTP请求可能会发送回对象的更新版本作为响应。我需要相应地更新表格。
我用BehaviorSubject实现了类似的东西(这些对象的列表),但是不确定如何用表单来实现。
编辑:很抱歉,不包含代码。相当混乱,所以这里是一个摘要。
这是我现在拥有的:
export class EditQuestionnaire implements OnInit {
questionnaireForm: FormGroup;
questionnaire: Observable<Questionnaire>;
// constructor with its dependencies omitted
ngOnInit() {
this.questionnaireForm = this.fb.group({
'id': [''],
'submitted': [false],
'questions': this.fb.array(
[]
),
});
this.questionnaire = this.questionnaireService.getQuestionnaireGeneral(); // This is an observable of a BehaviorSubject that gets updated in a service with every call to getQuestionnaire
this.questionnaireService
.getQuestionnaire(this.questionnaire.id)
.subscribe(questionnaire => {
this.questionnaireForm = this.loadQuestionnaire(questionnaire); // loads the questionnaire into the form
});
}
...
}
我还有一个儿童成分,表示问卷中的一个问题。在这里,我检测到更改:
export class QuestionComponent implements OnInit {
@Input() questionForm: FormGroup;
@Input() questionnaireId: string;
// constructor and dependencies omitted
get text() {
return this.questionForm.get('text') as FormControl;
}
get answers() {
return this.questionForm.get('answers') as FormArray;
}
get id() {
return this.questionForm.get('id') as FormControl;
}
get comment() {
return this.questionForm.get('comment') as FormControl;
}
ngOnInit() {
const questionId = this.id.value;
this.comment.valueChanges
.pipe(
debounce(() => interval(2000))
)
.subscribe(newValue => {
this.saveComment(questionId, newValue);
});
for (const answer of this.answers.controls) {
this.answers.valueChanges.subscribe(val => {
const answerId = answer.get('id').value;
this.saveAnswer(questionId, answer);
});
}
saveComment(questionId: string, comment: string) {
this.questionnaireService.updateComment(questionnaireId, questionId, comment).subscribe(); // no need to rebuild here
}
saveAnswer(questionId: string, answerId: string) {
this.questionnaireService.updateAnswer(questionnaireId, questionId, answerId).subscribe(questionnaire => { /* trigger the form to rebuild */ })
}
}
某些问题的答案可能会引发后续问题,因此将从后端发回一份全新的调查表。我在这里遇到的问题是valueChanges侦听器将新调查表识别为更改,并且我的应用程序陷入了HTTP请求的无限循环中。
任何想法如何解决此问题?
更新:
最终我最终使用EventEmitter将接收到的调查表对象传递给父组件,然后在其中重建表单。
答案 0 :(得分:0)
我假设您通过组件触发了来自服务的请求。要从组件更新反应式表单对象,可以直接分配它。例如,如果您这样声明反应式:
this.form = new FormGroup({
name: new FormControl()
})
您可以像这样简单地更新名称:
let name = "Kyle";
this.form.controls.name.value = name;
在以下Angular文档中找到: