我使用Angular 5,反应形式方法。
我在Angular Material对话框中有一个表单,我用它来输入和编辑数据。我的构造函数看起来像这样:
constructor(public formBuilder: FormBuilder,
public documentService: DocumentService,
@Inject(MAT_DIALOG_DATA) public data: any) {
this.createForm();
if (this.data.edit) {
this.setValues();
}
this.setTitles();
}
createForm
调用创建了我在异步验证中的反应形式:
createForm() {
this.documentForm = this.formBuilder.group({
...
documentNumber: new FormControl('',
{
updateOn: 'blur',
validators: [Validators.required],
asyncValidators: [this.checkDocumentNumber.bind(this)]
}),
...
});
}
如果对话框在'编辑'模式,setValues
调用修补需要编辑的数据:
setValue() {
this.form.patchData({
...
documentNumber: this.data.document.documentNumber
...
});
}
setTitles
调用设置对话框标题。
checkDocumentNumber
调用从服务器获取boolean
值:
checkDocumentNumber(control: AbstractControl): Observable<ValidationErrors | null> {
const formValue = this.form.value;
return this.documentService
.checkDocumentNumber(new Document(this.data.edit ? this.data.document.id : 0,
form.documentNumber)).pipe(map((response: boolean) => {
return response ? { inUse: true } : null;
}));
}
API调用是:
checkDocumentNumber(doc: Document) {
return this.http.post(`/Documents/Inbox/CheckDocumentNumber`, doc);
}
&#39>编辑&#39;中的表单对话框这样调用模式:
this.dialogService.open(DocumentDialogComponent,
{
data: {
edit: true,
document: this.document
}
});
我遇到的问题是,当我打开编辑文档数据的对话框时,会进行9次API调用来检查文档编号。前5个被取消,然后一个返回200
,另一个被取消,最后两个返回200
。
应用程序不同部分的相同情况让我取消了3次200
次调用。
如何阻止角度进行这些不必要的API调用?在Angular 5之前,updateOn
标志不存在,所以我认为这样做不会发生。
以下是正在进行的API调用的屏幕截图:
答案 0 :(得分:0)
Angular 会在每次值更改时执行请求。文档仅在同步验证器通过 "to avoid potentially expensive async validation processes (such as an HTTP request)"
时指定异步验证器这是我认为正在发生的事情:
updateOn: 'blur'
用于用户交互。当您通过代码更改值时,它不适用。
您实例化表单 -> 验证器被触发,触发请求。
您在 patchData()
中的 setValue()
-> 再次触发验证器。
我猜 Angular 在内部使用 switchMap 来验证 Observable,如果您更改了值,这将解释取消
我不知道您是如何获得 9 个请求的,为此我需要查看完整代码(@EstusFlask 评论,http://stackoverflow.com/help/mcve)。
什么可能有帮助:
添加一些同步验证器。 Validators.required
将避免请求空值,包括初始 ''
不要在创建表单后单独修补默认值,而是计算创建的默认值。
在默认为空的情况下不需要 required
,但在其他情况下需要,我觉得它更干净。
const defaultDocumentNumber = this.data.edit ? this.data.document.documentNumber : '';
...
documentNumber: new FormControl(defaultDocumentNumber, ...
我猜您在表单中还有其他触发验证的控件。这或许可以解释你是如何接到 9 个电话的。
如果是这种情况,您可以使用 FormControl.patchValue()
的第二个参数 options
来避免某些验证触发器,特别是 emitEvent
和 onlySelf
字段。
同样,如果没有可重复的例子,就不能说。看看docs。