Angular 8:如果前一个值与当前值相同,则反应式表单字段停止异步调用

Angular 8: Reactive form field stop async call if the previous value is same as the current value

我有一个用于输入名称的反应式表单输入字段,该字段还有一个异步验证器来检查输入的名称是否已经存在于数据库中,一旦提交表单,它将进入编辑模式,现在问题是一旦表单进入编辑状态,如果我们刷新页面,或者如果我们清除名称并再次输入相同的名称,表单将再次发送一个异步请求来检查名称,我想停止它。

现在有很多肮脏的方法来停止异步调用,即使我可以在服务器端处理它,但如果输入的名称与以前的名称相同,我不想向服务器发送额外的请求

TS

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import * as $ from 'jquery'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import Swal from 'sweetalert2'
import { CompanyInformation } from 'src/app/data/models/company/company-Information.model';
import { CompanyApiService } from '../../service/company-api.service';
import { Observable } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';

@Component({
  selector: 'app-company-information',
  templateUrl: './company-information.component.html',
  styleUrls: ['./company-information.component.css'],
  providers: [CompanyApiService]
})
export class CompanyInformationComponent implements OnInit {
  companyInfo: CompanyInformation;
  companyInfoForm: FormGroup;
  isEdit: boolean = false;

constructor(private apiService: CompanyApiService,private modalService: NgbModal) { }

ngOnInit() {
  //Call these function when the page load
  this.createCompanyInfoForm(); //Create company information reactive form
}

//Create company information form
createCompanyInfoForm() {
  this.companyInfoForm = new FormGroup({
  'companyName': new FormControl(null, {
    validators: [Validators.required],
    updateOn: 'blur',
    asyncValidators: this.checkDuplicateCompany.bind(this)
    }),
  })
}

//Check duplicate company name
checkDuplicateCompany(control: FormControl): Promise<any> | Observable<any> {
 const promise = new Promise<any>((resolve, reject) => {
  this.apiService.checkDuplicateCompany(control.value)
    .subscribe((data: BaseEntityModel<CompanyInformation>) => {
      if (data.status === 1) {
        //Return resolve
        resolve({ 'duplicateCompany': true });
      } else {
        resolve(null);
      }
    }, err => {
      //Show error toast message
      this.msgService.showToastMessage('error', err.statusText);
    });
 });
 return promise;
}

//Save
saveComInfo() {
 //Call the API if in save mode
 if (!this.isEdit) {
  //If form is valid
  if (this.companyInfoForm.valid) {
    //Insert all form data to CompanyInformation model
    this.companyInfo = new CompanyInformation(this.companyInfoForm.value);
    //Set companyId if available
    this.companyInfo.companyID = this.datashareService.getCompanyId;
    //Call the service
    this.apiService.saveCompany(this.companyInfo)
      .subscribe((data: BaseEntityModel<CompanyInformation>) => {
         //If save success
         if (data.status === 0) {
           if (data.entity.length > 0) {
           this.datashareService.setCompanyId(data.entity[0]);
         }
          //Change the edit flag value
          this.isEdit = !this.isEdit;
          //Disable the form
          this.companyInfoForm.disable();
        } else {
           //Show error message
           this.msgService.showToastMessage('error', data.message);
        }
    }, (err: any) => {
      //Show error message
      this.msgService.showToastMessage('error', err.statusText)
    });
  } else {
    //Mark all fields as touched to display validation
    this.companyInfoForm.markAllAsTouched();       
  }
} else { // If edit in edit mode
   //Change the edit flag value
   this.isEdit = !this.isEdit;
   //Enable the form
   this.companyInfoForm.enable();
  }
}

如果你根据模式绑定 asyncValidators 会怎么样,假设一个变量模式有开关 'add'/'edit'。提交表单后,模式可以替换为 'edit'。

let mode = 'add'; //initialize with 'add' then switch to edit after submit.
createCompanyInfoForm() {
  this.companyInfoForm = new FormGroup({
  'companyName': new FormControl(null, {
    validators: [Validators.required],
    updateOn: 'blur',
    asyncValidators: this.mode == 'add' ? this.checkDuplicateCompany.bind(this) : call_different_method_to_bind
    }),
  })
}