Angular Material 使用数组自动完成<Object>

Angular Material Autocomplete Using An Array<Object>

我有以下 Stackblitz: AutoComplete - StackBlitz

一旦用户select选择了一个选项,然后清除输入并开始输入,过滤将停止工作。

用户如何 select 一个选项并开始在只有有效结果显示的地方输入?

它停止工作,因为您在 rxjs 流中遇到错误。

value 可以是 stringoption 对象。您必须通过 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())
);

Forker Stackblitz

另请参阅 显示值自动完成 Angular material docs

中的示例

更新

OP 认为这个实现有问题:

I forked off yours again and added a button just for ease. If you select an option, click continue, backspace the "0" from the zip code, click continue, add the zero back to the input, click continue. This gives you undefined https://stackblitz.com/edit/angular-material-autocomplete-eg-4w15ki?file=app/autocomplete-filter-example.html

但是如果你查看 material 文档,它会按预期工作,因为在 Angular material 自动完成 Angular material 中没有 select 匹配或强制 selection 功能 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