如何对复杂对象使用角度材质自动完成功能?

问题描述 投票:0回答:1

我正在构建一个在 Angular 16 中使用 Angular Material 的应用程序。我有 ngrx 状态管理来收集一系列对象以供选择。我希望输入在从自动完成选项中选择一个对象时显示该对象的名称属性。我目前正在使用带有 mat-autocomplete 的 matInput。

import { Component, OnInit } from '@angular/core';
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {AsyncPipe} from '@angular/common';
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {MatInputModule} from '@angular/material/input';
import {MatFormFieldModule} from '@angular/material/form-field';
import { TokenNameWithId } from '../../../shared/models/card.model';
import { Observable, combineLatest, debounceTime, map, startWith } from 'rxjs';
import { Store } from '@ngrx/store';
import { selectAllTokenNames } from '../+state/token-names.selectors';

@Component({
  selector: 'tokenator-tokens-dropdown',
  standalone: true,
  imports: [FormsModule,
    MatFormFieldModule,
    MatInputModule,
    MatAutocompleteModule,
    ReactiveFormsModule,
    AsyncPipe
  ],
  providers: [
  ],
  templateUrl: './tokens-dropdown.component.html',
  styleUrl: './tokens-dropdown.component.scss',
})
export class TokensDropdownComponent implements OnInit {
  public tokenNamesControl = new FormControl<string>('', {
    nonNullable: true,
  });
  public filteredTokenNames!: Observable<TokenNameWithId[]>;
  private tokenNames$ = this.store.select(selectAllTokenNames);

  constructor(private store: Store) {
  }

  ngOnInit(): void {
    this.filteredTokenNames = combineLatest([
      this.tokenNamesControl.valueChanges.pipe(startWith('')),
      this.tokenNames$,
    ]).pipe(
      debounceTime(250),
      map(([value, tokenNamesWithId]) => value ? this._filter(value, tokenNamesWithId) : tokenNamesWithId
    ));
  }

  private _filter(value: string, tokenNamesWithId: TokenNameWithId[]): TokenNameWithId[] {
    const filterValue = value.toLowerCase();
    return tokenNamesWithId.filter((tokenNameWithId: TokenNameWithId) => tokenNameWithId.displayName.includes(filterValue));
  }
}
.example-form {
    min-width: 150px;
    max-width: 500px;
    width: 100%;
  }
  
  .example-full-width {
    padding-top: 10px;
    width: 100%;
  }
<form class="example-form">
    <mat-form-field class="example-full-width">
        <mat-label>Token</mat-label>
        <input 
            type="text"
            placeholder="Select a token"
            aria-label="Token name"
            matInput
            [formControl]="tokenNamesControl"
            [matAutocomplete]="auto">
        <mat-autocomplete #auto="matAutocomplete">
            @for (tokenName of filteredTokenNames | async ; track tokenName) {
                <mat-option [value]="tokenName">{{tokenName.displayName}}</mat-option>
            }
        </mat-autocomplete>
    </mat-form-field>
</form>

这会导致 matInput 出现奇怪的行为,其中自动完成搜索有效,我可以选择一个对象,但显示的值是

[object Object]
。这是有道理的,因为自动完成的基础选择值是一个对象,但我希望输入显示
tokenName.displayName
的文本,就像我的
<mat-options>
一样。

有没有办法让

matInput
显示从自动完成中选择的对象的属性?或者,当我从数组中选择更复杂的对象来保留工作自动完成功能时,是否应该使用更好的角度材料组件配对?

angular angular-material autocomplete ngrx
1个回答
1
投票

您需要使用

[displayWith]
属性来自定义所选选项的显示文本。

displayFn(tokenName: any): string {
  return tokenName && tokenName.displayName ? tokenName.displayName : '';
}
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
    ...
</mat-autocomplete>

参考:设置单独的控制和显示值

© www.soinside.com 2019 - 2024. All rights reserved.