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
}),
})
}
我有一个用于输入名称的反应式表单输入字段,该字段还有一个异步验证器来检查输入的名称是否已经存在于数据库中,一旦提交表单,它将进入编辑模式,现在问题是一旦表单进入编辑状态,如果我们刷新页面,或者如果我们清除名称并再次输入相同的名称,表单将再次发送一个异步请求来检查名称,我想停止它。
现在有很多肮脏的方法来停止异步调用,即使我可以在服务器端处理它,但如果输入的名称与以前的名称相同,我不想向服务器发送额外的请求
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
}),
})
}