角材料自动完成,初始化过滤选项以查看所有选项

时间:2018-08-31 10:03:28

标签: angular autocomplete angular-material observable

我有一个Tour数组,该数组由组件中的API用远程数据初始化。

tours: Tour[] = [];
filteredOptions: Observable<Tour[]>;

constructor(
  private api: APIService,
) { }

ngOnInit() {
  this.api.getTours().subscribe(
   data => { this.tours = data; this.filteredOptions = of(data); }
  );
}

这些游览将显示在具有自动完成功能的垫输入中

<mat-form-field class="long tour-sel">
   <input matInput type="text" [formControl]="myControl" [matAutocomplete]="tourList" placeholder="Select a tour"/>
</mat-form-field>
<mat-autocomplete #tourList="matAutocomplete">
   <mat-option *ngFor="let tour of filteredOptions | async" [value]="tour">{{tour.name}}</mat-option>
</mat-autocomplete>

在组件中,这是侦听更改并过滤选项的简单代码

this.filteredOptions = this.myControl.valueChanges.pipe(
  startWith(''),
  map(value => this._filterTour(value))
);
private _filterTour(value: string): Tour[] {
   const filterValue = value.toLowerCase();
   return this.tours.filter(option => option.name.toLowerCase().includes(filterValue));
}

如果如上所示,我在订阅函数中初始化filteredOptions数组,那么当我单击输入时,我会在自动完成面板中看到所有选项,但是当我开始键入内容时,没有任何变化,并且不过滤结果(未调用过滤器函数)。如果在单击输入时删除this.filteredOptions = of(data);,则看不到任何选项,但过滤有效,当删除输入中键入的内容时,将查看所有选项。 我希望看到输入的第一个焦点上的所有选项,而不会破坏过滤功能。

1 个答案:

答案 0 :(得分:1)

可能的解决方案:

ngOnInit() {
  this.api.getTours().subscribe(
   data => { 
       this.tours = data;
       this.filteredOptions = this.myControl.valueChanges.pipe(
           startWith(''),
           map(value => this._filterTour(value))
       );
  });
}

在subscription函数中初始化filteredOptions(this.filteredOptions = of(data);)时,它会覆盖其先前的任何引用(对valueChanges.pipe的引用),然后异步管道订阅此新引用并将自动完成功能设置为此静态列表,因此过滤不起作用。

但是,如果我们没有在订阅函数中对其进行初始化,则在调用valueChanges.pipe(startWith(''))时this.tours为空,因此列表开头是空的。

因此,解决方案可能是在填充“ this.tours”之后(即在订阅函数内部)使用valueChanges.pipe()初始化filteredOptions。