如何在自动完成中使用 [displayWith] 管理异步?

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

我的角度反应形式有一个自动完成功能。 我想显示 myObject.name 但使用 myObject.id 作为值。

当表单预填充现有值时,我需要根据 myObject.id 获取 myObject.name,这需要一些时间。不幸的是,自动完成中显示的是 id 而不是名称。我无法让它发挥作用。

我尝试使用 observable,但看起来 displayWith 不支持它。我怎样才能做到这一点?

打字稿:

    public displayWith(id: string): string {
    if (!id) {
        return '';
    }
    let freespinName = '';
    this.freespins$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(freespins => {
        const found = freespins.find((freespin: Freespin) => freespin.id === id);
        freespinName = found?.name || id;
    });

    return freespinName;
}

HMTL:

                     <mat-label>Freespin</mat-label>
                        <input type="text"
                               placeholder="Select a freespin"
                               matInput
                               formControlName="rewardId"
                               [matAutocomplete]="auto">
                        <mat-autocomplete requireSelection #auto="matAutocomplete"
                                          [displayWith]="displayWith.bind(this)">
                            <mat-option *ngFor="let freespin of filteredFreespins[i] | async"
                                        [value]="freespin.id">
                                {{freespin.name}}
                            </mat-option>
                        </mat-autocomplete>
                    </mat-form-field>
javascript angular asynchronous angular-material autocomplete
2个回答
0
投票

请将这段代码写在ngOnInit上,我们需要在里面进行API调用

displayWith

请注意,这只是伪代码,但您可以使用此方法并尝试解决您的问题!

export class SomeComponent {

    nameIdMap = {};
    
    ngOnInit() {
    
        this.freespins$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(freespins => {
                this.nameIdMap = {};
                // creating this hashmap will ensure that you will immediately get the value of name
                freespins.forEach((freespin: any) => {
                    this.nameIdMap[freespin.id]=freespin.name;
                });
            });
    
    }
    
    diplayWith(id: string): string {
        return this.nameIdMap?.[id]?.name
    }

}

0
投票

如果您使用的是 Angular 16+,您可以在此处使用信号

  private freespins = toSignal(this.freespins$);

displayFn(id: string) => string {
        return this.freespins()!.find((freespin) => freespin.name === id)?.name || '';
      }

你也可以像这样返回函数

  displayFn(): (freespins: any) => string {
    return (id: string) =>
      this.freespins()!.find((freespin) => freespin.name === id)?.name ||
      '';
  }

此外,如果

this.freespins$
BehaviourSubject
,您无需订阅即可获取该值

private freeSpins$ = new BehaviorSubject(this.options);
  displayFn2(user: User): string {
    return (
      this.freeSpins$
        .getValue()!
        .find((freespin) => freespin.name === user.name)?.name || ''
    );
  }

查看此处的示例 https://stackblitz.com/edit/bdx7mn?file=src%2Fexample%2Fautocomplete-display-example.ts,src%2Fexample%2Fautocomplete-display-example.html

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