【问题标题】:mat autocomplete for a non-async datamat 自动完成非异步数据
【发布时间】:2019-02-21 19:48:34
【问题描述】:

我有一个小时列表框(角度材料列表框,由数字 1 到 12 组成),我将其转换为垫子自动完成。

列表框不是反应形式

下面是我创建模板以提取静态列表选项的 html。

<table>
  <tr>
    <td>
      <mat-form-field>
        <input type="text" [(ngModel)]="fromCreateDateTime.Hour" [ngModelOptions]="{standalone: true}" placeholder="Hour" matInput [matAutocomplete]="autoFromCreateDateTimeHour">

        <mat-autocomplete #autoFromCreateDateTimeHour="matAutocomplete" placeholder="Hour" [displayWith]="displayFn">
          <mat-option *ngFor="let hour of hoursList" [value]=" hour ">{{hour.name}}
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>
    </td>
  </tr>
</table>

这里的hoursList 是一个如下定义的数组。它不是可观察的。

hoursList: Array, any > =
  export const hoursList: Array < any > = [{
    name: "00",
    value: 0
  }, {
    name: "01",
    value: 1
  }, {
    name: "02",
    value: 2
  }, {
    name: "03",
    value: 3
  }, {
    name: "04",
    value: 4
  }, {
    name: "05",
    value: 5
  }, {
    name: "06",
    value: 6
  }, {
    name: "07",
    value: 7
  }, {
    name: "08",
    value: 8
  }, {
    name: "09",
    value: 9
  }, {
    name: "10",
    value: 10
  }, {
    name: "11",
    value: 11
  }, {
    name: "12",
    value: 12
  }];

如何将过滤器(在 mat 输入中键入)应用于 mat 自动完成,因为这里的数据是非异步数据。

【问题讨论】:

    标签: angular filter autocomplete angular-material angular6


    【解决方案1】:

    如果您正在考虑仅使用字符串数组,这很简单:

    import {Component, OnInit} from '@angular/core';
    import {FormControl} from '@angular/forms';
    import {Observable} from 'rxjs';
    import {map, startWith} from 'rxjs/operators';
    
    @Component({
      selector: 'autocomplete-filter-example',
      templateUrl: 'autocomplete-filter-example.html',
      styleUrls: ['autocomplete-filter-example.css'],
    })
    export class AutocompleteFilterExample implements OnInit {
      myControl = new FormControl();
      options: string[] = [
        "00",
        "01",
        "02",
        "03",
        "04",
        "05",
        "06",
        "07",
        "08",
        "09",
        "10",
        "11",
        "12",
      ];
    
      filteredOptions: Observable < string[] > ;
    
      ngOnInit() {
        this.filteredOptions = this.myControl.valueChanges
          .pipe(
            startWith(''),
            map(value => this._filter(value))
          );
      }
    
      private _filter(value: string): string[] {
        const filterValue = value.toLowerCase();
        return this.options.filter(
          option => option.toLowerCase().includes(filterValue)
        );
      }
    
    }
    

    还有你的模板:

    <form class="example-form">
      <mat-form-field class="example-full-width">
        <input type="text" 
          placeholder="Pick one" 
          aria-label="Number" 
          matInput 
          [formControl]="myControl" 
          [matAutocomplete]="auto">
        <mat-autocomplete #auto="matAutocomplete">
          <mat-option 
            *ngFor="let option of filteredOptions | async" 
            [value]="option">
            {{option}}
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>
    </form>
    

    这里有一个Sample StackBlitz 供您参考。

    【讨论】:

    • OP 说他们没有使用表单控件。
    【解决方案2】:

    您可以使用 (ngModelChange) 和 [ngModel] 代替 [(ngModel)]。像这样的:

    模板:

    <mat-form-field>
       <mat-label>Some label</mat-label>
       <input type="text"
          matInput
          [ngModel]="someObject"
          [matAutocomplete]="autocopmlete"
          (focus)="filter('')"
          (ngModelChange)="filter($event)">
          <mat-autocomplete
             #autocopmlete="matAutocomplete"
             [displayWith]="displayName">
          <mat-option
             *ngFor="let item of filteredObject"
             [value]="item">
             {{ item.name }}
          </mat-option>
       </mat-autocomplete>
    </mat-form-field>
    

    组件:

      someObject = [
         { name: 'Alex' },
         { name: 'Morty' }
      ]
    
      filteredObject = []
    
      filter(value = '') {
          if (typeof value !== 'string') {
              return;
          }
        
          this.filteredObject = this.someObject.filter(
              a => ~a.name.toLocaleLowerCase().indexOf(value.toLocaleLowerCase())
          );
      }
    
    
      displayName(item: any) {
          return item ? item.name : '';
      }
    

    【讨论】:

      猜你喜欢
      • 2015-06-14
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-18
      • 1970-01-01
      • 2021-10-24
      • 2012-12-18
      相关资源
      最近更新 更多