首页 > 解决方案 > 如何在组合框选择上添加警告?

问题描述

因此,我有一个现有的组合框,用户可以在其中键入和搜索组合框中的现有选项。我想要做的是在用户键入不属于组合框中选项的单词时添加警告。这是我现在的代码:

<mat-form-field appearance="outline" class="width-1">
                <mat-label>Aircraft Type (ICAO)</mat-label>
                <!-- test autocomplete aircraft type -->
                <input
                  type="text"
                  placeholder="Aircraft Type (ICAO)"
                  aria-label="Aircraft Type (ICAO)"
                  matInput
                  formControlName="aircraftType"
                  [matAutocomplete]="type"
                  (input)="onAircraftTypeChange()"
                />
                <mat-autocomplete
                  #type="matAutocomplete"
                  (optionSelected)="onSelectAircraftType($event.option.value)"
                  [displayWith]="displayAircraftTypeFn"
                >
                  <mat-option
                    *ngFor="let type of filteredAircraftTypes | async"
                    [value]="type"
                  >
                    {{ type.label }}
                  </mat-option>
                </mat-autocomplete>
                <!-- end test autocomplete -->
              </mat-form-field>

现有组合框

我想在表单字段上方添加警告。

标签: angulartypescriptsearchcomboboxwarnings

解决方案


不建议在表单字段上方放置警告或错误消息,因为这会导致用户出现意外行为并违反最小意外原则

相反,当用户输入文本并且选项不包含特定文本时,<mat-autocomplete>下拉菜单不会显示任何选项,因此可以在元素<mat-error>下方显示。<matInput>


.component.html

<mat-form-field appearance="outline" class="width-1">

    <mat-label>Aircraft Type (ICAO)</mat-label>
    <!-- test autocomplete aircraft type -->
    <input
      type="text"
      placeholder="Aircraft Type (ICAO)"
      aria-label="Aircraft Type (ICAO)"
      matInput
      formControlName="aircraftType"
      [matAutocomplete]="type"
      (input)="onAircraftTypeChange()"
    />
    <mat-autocomplete #type="matAutocomplete" (optionSelected)="onSelectAircraftType($event.option.value)"
      [displayWith]="displayAircraftTypeFn">
      <mat-option *ngFor="let type of filteredAircraftTypes | async" [value]="type">
        {{ type.label }}
      </mat-option>
    </mat-autocomplete>
    <!-- end test autocomplete -->

    <mat-error *ngIf="f.aircraftType.errors">
      <mat-error *ngIf="f.aircraftType.errors['notFound']">Not found!</mat-error>
    </mat-error>

</mat-form-field>

访问内置的valueChangesObservable 进行airCraftType控制:

  1. startWith- 用空字符串设置初始值。
  2. mergeMap- 根据输入的文本过滤选项。
  3. tap-如果 (2) 返回空数组,则控制setError任务。airCraftType否则,清除错误。

.component.ts

import { mergeMap, map, Observable, of, startWith, tap } from 'rxjs';

ngOnInit() {
  ...

  this.filteredAircraftTypes = this.form.controls[
      'aircraftType'
    ].valueChanges.pipe(
      startWith(''),
      mergeMap(value => this._filter(value)),
      tap(filterOptions => {
        this.form.controls['aircraftType'].markAsTouched();
        this.form.controls['aircraftType'].markAsDirty();

        if (filterOptions.length == 0) {
          this.form.controls['aircraftType'].setErrors({ notFound: true });
        } else {
          this.form.controls['aircraftType'].setErrors(null);
        }
      })
    );
}

private _filter(value: string): Observable<IAirCraft[]> {
    const filterValue = value.toLowerCase();

    return this.aircraftTypes.pipe(
      map(options =>
        options.filter(option =>
          option.label.toLowerCase().includes(filterValue)
        )
      )
    );
}

StackBlitz 上的示例演示


参考

添加自定义过滤器 - 自动完成 | 角材料

startWith - 学习 RxJS


推荐阅读