如何在 Angular 中触发自定义错误验证的即时 mat-error
How trigger immediate mat-error on custom error validation in Angular
如何让我的自定义 mat-error
立即触发?我知道 Angular 文档中有一个示例,但无法让它发挥作用。我的验证不是针对 empty
,也不是针对某个 type
,例如 email
。
当我在下拉字段中进行搜索但未找到任何记录时,我希望显示我的错误。项目下方的普通 <div>
会立即在 *ngIf
上触发,但不会在 mat-error
上触发。我也尝试用 .innerHTML
更新 mat-error,但该字段不存在。我确定这是因为 Angular 还没有创建它。
这是我的 HTML:
<mat-form-field>
<input type="text" placeholder="Customer Search" id="CustomerId" name="CustomerId" aria-label="Number" matInput [formControl]="myCustomerSearchControl"
[matAutocomplete]="auto" (keyup)="onCustomerSearch($event)"
required [errorStateMatcher]="matcher">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="setLoadId($event)">
<mat-option *ngFor="let customer of customerArray" [value]="customer.Display">
{{ customer.Display }}
</mat-option>
</mat-autocomplete>
<mat-error id="customer-error" *ngIf="noCustomersFound.value">
{{noCustomersFound.message}}
</mat-error>
</mat-form-field>
<div>
<span class="errorMessage" *ngIf="noCustomersFound.value">
{{noCustomersFound.message}}
</span>
</div>
这是我在 .ts 文件中的方法和我尝试过的一些东西:
onCustomerSearch(search) {
let searchObject = new SearchObject();
searchObject.Entity = 'Customer';
searchObject.SearchString = search.key;
searchObject.SearchClauses = [{Column: 'sCustomerName'}];
searchObject.DisplayColumn = 'sCustomerName';
this.loadDataService.searchByEntity(searchObject)
.subscribe(data => {
if (data.length < 1) {
this.noCustomersFound.value = true;
this.noCustomersFound.message = 'No match found.'
document.getElementById('customer-error').innerHTML = 'No match found.';
} else {
this.noCustomersFound.value = false;
this.noCustomersFound.message = '';
}
this.customerArray = data;
});
}
首先,您需要一个自定义验证器。
您可以通过在 CLI 中键入以下命令来生成指令,该指令将用于验证 angular 中的 FormControl:
ng g directive customValidator
该指令的功能应与此类似:
//make sure to post this code below the class closing curly brackets.
export function customerSearchIsEmpty(searchResultsLength): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
const isValid = searchResultsLength ? searchResultsLength > 0 : false;
return isValid ? null :
{ 'customerSearchIsEmpty': { value: control.value } }; };}
创建 FormControl 后,您应该动态添加新的验证器:
this.registeredForm.controls['myCustomerSearchControl'].setValidators([customerSearchIsEmpty(null)])
在 onCustomerSearch 函数所在的 TS 文件中,
您应该再添加一项功能:
myCustomerSearchControlIsInvalid() {
this.myCustomerSearchControl.updateValueAndValidity();
//instead of registeredForm, use your FormGroup name.
if (this.registeredForm.hasError('customerSearchIsEmpty')) {
this.noCustomersFound.message = 'No customer found'; //or any other message
} else {
return false;
} return true;
}
您应该修改您的代码以对 myCustomerSearchControlIsInvalid() 函数的结果做出反应:
<mat-error *ngIf="myCustomerSearchControlIsInvalid()">
{{noCustomersFound.message}}
</mat-error>
最后,您应该在 onCustomerSearch() 函数中添加这行代码。
onCustomerSearch(search) {
let searchObject = new SearchObject();
searchObject.Entity = 'Customer';
searchObject.SearchString = search.key;
searchObject.SearchClauses = [{Column: 'sCustomerName'}];
searchObject.DisplayColumn = 'sCustomerName';
this.loadDataService.searchByEntity(searchObject)
.subscribe(data => {
customerSearchIsEmpty(data.length);
this.customerArray = data;
});}
希望对您有所帮助。
如何让我的自定义 mat-error
立即触发?我知道 Angular 文档中有一个示例,但无法让它发挥作用。我的验证不是针对 empty
,也不是针对某个 type
,例如 email
。
当我在下拉字段中进行搜索但未找到任何记录时,我希望显示我的错误。项目下方的普通 <div>
会立即在 *ngIf
上触发,但不会在 mat-error
上触发。我也尝试用 .innerHTML
更新 mat-error,但该字段不存在。我确定这是因为 Angular 还没有创建它。
这是我的 HTML:
<mat-form-field>
<input type="text" placeholder="Customer Search" id="CustomerId" name="CustomerId" aria-label="Number" matInput [formControl]="myCustomerSearchControl"
[matAutocomplete]="auto" (keyup)="onCustomerSearch($event)"
required [errorStateMatcher]="matcher">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="setLoadId($event)">
<mat-option *ngFor="let customer of customerArray" [value]="customer.Display">
{{ customer.Display }}
</mat-option>
</mat-autocomplete>
<mat-error id="customer-error" *ngIf="noCustomersFound.value">
{{noCustomersFound.message}}
</mat-error>
</mat-form-field>
<div>
<span class="errorMessage" *ngIf="noCustomersFound.value">
{{noCustomersFound.message}}
</span>
</div>
这是我在 .ts 文件中的方法和我尝试过的一些东西:
onCustomerSearch(search) {
let searchObject = new SearchObject();
searchObject.Entity = 'Customer';
searchObject.SearchString = search.key;
searchObject.SearchClauses = [{Column: 'sCustomerName'}];
searchObject.DisplayColumn = 'sCustomerName';
this.loadDataService.searchByEntity(searchObject)
.subscribe(data => {
if (data.length < 1) {
this.noCustomersFound.value = true;
this.noCustomersFound.message = 'No match found.'
document.getElementById('customer-error').innerHTML = 'No match found.';
} else {
this.noCustomersFound.value = false;
this.noCustomersFound.message = '';
}
this.customerArray = data;
});
}
首先,您需要一个自定义验证器。
您可以通过在 CLI 中键入以下命令来生成指令,该指令将用于验证 angular 中的 FormControl:
ng g directive customValidator
该指令的功能应与此类似:
//make sure to post this code below the class closing curly brackets.
export function customerSearchIsEmpty(searchResultsLength): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
const isValid = searchResultsLength ? searchResultsLength > 0 : false;
return isValid ? null :
{ 'customerSearchIsEmpty': { value: control.value } }; };}
创建 FormControl 后,您应该动态添加新的验证器:
this.registeredForm.controls['myCustomerSearchControl'].setValidators([customerSearchIsEmpty(null)])
在 onCustomerSearch 函数所在的 TS 文件中, 您应该再添加一项功能:
myCustomerSearchControlIsInvalid() {
this.myCustomerSearchControl.updateValueAndValidity();
//instead of registeredForm, use your FormGroup name.
if (this.registeredForm.hasError('customerSearchIsEmpty')) {
this.noCustomersFound.message = 'No customer found'; //or any other message
} else {
return false;
} return true;
}
您应该修改您的代码以对 myCustomerSearchControlIsInvalid() 函数的结果做出反应:
<mat-error *ngIf="myCustomerSearchControlIsInvalid()">
{{noCustomersFound.message}}
</mat-error>
最后,您应该在 onCustomerSearch() 函数中添加这行代码。
onCustomerSearch(search) {
let searchObject = new SearchObject();
searchObject.Entity = 'Customer';
searchObject.SearchString = search.key;
searchObject.SearchClauses = [{Column: 'sCustomerName'}];
searchObject.DisplayColumn = 'sCustomerName';
this.loadDataService.searchByEntity(searchObject)
.subscribe(data => {
customerSearchIsEmpty(data.length);
this.customerArray = data;
});}
希望对您有所帮助。