在form.setValues()

时间:2017-11-05 22:07:59

标签: angular typescript angular5

我使用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调用的屏幕截图:

API calls being made

1 个答案:

答案 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 来避免某些验证触发器,特别是 emitEventonlySelf 字段。
    同样,如果没有可重复的例子,就不能说。看看docs