Array <Object>を使用したAngularMaterialのオートコンプリート

Aug 26 2020

私は次のStackblitzを持っています:オートコンプリート-StackBlitz

ユーザーがオプションを選択し、入力をクリアして入力を開始すると、フィルタリングは機能しなくなります。

ユーザーがオプションを選択して、有効な結果のみが表示される場所で入力を開始するにはどうすればよいですか?

回答

1 yurzui Aug 26 2020 at 01:22

rxjsストリームでエラーが発生したため、動作を停止します。

valuestringまたはoptionオブジェクトにすることができます。map演算子を使用して適切にマップする必要があります。

の代わりに

.pipe(
  startWith(''),
  map(value => this._filter(value))
);

次のことを試してください。

.pipe(
  startWith(''),
  map(value => typeof value === 'string' ? value : value.address),
  map(address => address ? this._filter(address) : this.options.slice())
);

フォーカースタックブリッツ

Angularマテリアルドキュメントの表示値オートコンプリートの例も参照してください

更新

OPは、この実装には問題があると考えています。

もう一度フォークして、簡単にするためにボタンを追加しました。オプションを選択した場合は、[続行]をクリックし、郵便番号から「0」をバックスペースして、[続行]をクリックし、入力にゼロを追加して、[続行]をクリックします。これはあなたに未定義を与えますhttps://stackblitz.com/edit/angular-material-autocomplete-eg-4w15ki?file=app/autocomplete-filter-example.html

ただし、マテリアルドキュメントを確認すると、Angularマテリアルのオートコンプリートには一致時の選択または強制選択機能がないため、期待どおりに機能します。 https://github.com/angular/components/issues/3334

つまり、入力していて、入力した文字列がオートコンプリートの値と完全に一致する場合、FormControlの値は、期待どおりにオブジェクトではなく文字列のままになります。

それを強制するために、次のような単純なディレクティブを作成できます。

@Directive({
  selector: "[forceSelection]"
})
export class AutocompleteForceSelectionDirective implements AfterViewInit, OnDestroy {
  @Input() matAutocomplete: MatAutocomplete;

  @Input('forceSelection') key: string;

  private destroyed$ = new Subject(); constructor( @Host() @Self() private autoCompleteTrigger: MatAutocompleteTrigger, private ngControl: NgControl ) {} ngAfterViewInit() { this.autoCompleteTrigger.panelClosingActions .pipe( filter(e => !e || !e.source), takeUntil(this.destroyed$)
      )
      .subscribe(e => {
        const selected = this.matAutocomplete.options
          .map(option => option.value)
          .find(option => (this.key ? option[this.key] : option) === this.ngControl.value);

        if (selected) {
          this.ngControl.control.setValue(selected);
        }
      });
  }

  ngOnDestroy() {
    this.destroyed$.next();
  }
}

そしてそれをあなたの入力に適用します

<input ... [matAutocomplete]="auto" forceSelection="address">

https://stackblitz.com/edit/angular-material-autocomplete-eg-lih2bo?file=app%2Fautocomplete-force-selection.directive.ts