如何在Angular中自定义错误验证时立即触发mat-error

时间:2018-03-12 08:55:15

标签: html5 angular typescript angular-material-5

如何让我的自定义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;
      });
}

1 个答案:

答案 0 :(得分:1)

首先,您需要一个自定义验证器。

您可以通过在CLI中键入以下命令来生成用于以角度验证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;
  });}

我希望这会有所帮助。