角材料显示值自动完成

时间:2019-08-30 10:19:44

标签: angular autocomplete angular-material components

我想将物料自动完成组件创建为可重用组件。我正在通过[item]="stations"将对象传递给父级到子级。过滤不起作用。这是预期的行为material autocomplete。谁能告诉我我在哪里犯错了?

app-autocomplete.ts

export class MatFilterDownloadComponent implements OnInit, ControlValueAccessor {
  @Input()
  items: any[];

  constructor() {}

  myControl = new FormControl();
  filteredOptions: Observable<any[]>;

  private _backup: IComboBoxItem;
  private _value: IComboBoxItem;
  private _onChangeCallback: (_: any) => {};

  get value(): any {
    return this._value ? this._value.text : '';
  }

  @Input()
  set value(value: any) {
    console.log('value', value);
    if (!value) {
      return;
    }

    if (this._value && this._value.text === value) {
      return;
    }

    const items = this.items || [];
    const found = items.find((s) => s.text === value);
    console.log('found', found);
    if (!found) {
      return;
    }

    this._value = found;
    this._onChangeCallback(found);
  }

  ngOnInit() {
    this.filteredOptions = this.myControl.valueChanges.pipe(
      startWith(''),
      map((value) => (typeof value === 'string' ? value : value.value)),
      map((name) => (name ? this._filter(name) : this.items.slice())),
    );
  }

  displayFn(user?: any): string | undefined {
    console.log('user', user);
    return user ? user.text : undefined;
  }

  private _filter(name: string): any[] {
    const filterValue = name.toLowerCase();

    return this.items.filter((option) => option.text.toLowerCase().indexOf(filterValue) === 0);
  }

  writeValue(value: any) {
    this._value = value;
  }

  registerOnChange(fn: any) {
    this._onChangeCallback = fn;
  }

  registerOnTouched() {}

  clearInput() {
    this._backup = this._value;
    this._value = null;
  }

  undoInput() {
    this._value = this._backup;
  }
}

app-autocomplete.html

<div class="mat-filter-download-wrapper">
  <div class="mat-filter-download-wrapper__search">
    <mat-form-field appearance="outline" class="mat-filter-download-wrapper--search-input">
      <mat-label>Search</mat-label>
      <input type="text" placeholder="Pick one" matInput [(ngModel)]="value" [formControl]="myControl" [matAutocomplete]="auto" />
      <mat-autocomplete #auto="matAutocomplete" #auto="matAutocomplete" [displayWith]="displayFn">
        <mat-option *ngFor="let station of filteredOptions | async" [value]="station.text">
          {{ station.text }}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
</div>

app.ts

export class AppComponent implements OnInit {

  ngOnInit() {
    this.indexStations();
  }

indexStations() {
    this.orderService
      .indexStationsLite()
      .pipe(
        takeUntil(this.allSub),
        map((items) =>
          items.map(
            (station) =>
              ({
                text: this.titleCasePipe.transform(station.name),
                value: station.id,
              } as IDropdownItem),
          ),
        ),
      )
      .subscribe((stations) => {
        this.stations = stations;
      });
  }
}

app.html

<app-mat-filter-download
          [(ngModel)]="filterValues"
          [items]="stations"
          (ngModelChange)="filter()"
></app-mat-filter-download>

sample.json

[
   {
      "text":"station1",
      "value":"100"
   },
   {
      "text":"station2",
      "value":"200"
   },
   {
      "text":"station3",
      "value":"300"
   }
]

0 个答案:

没有答案