Автозаполнение углового материала, инициализация отфильтрованных опций для просмотра всех опций в фокусе - PullRequest
0 голосов
/ 31 августа 2018

У меня есть массив 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 голосов
/ 23 октября 2018

Возможное решение:

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

Когда в функции подписки инициализируется FilterOptions (this.filteredOptions = of(data);), он переопределяет любые из своих предыдущих ссылок (ссылка на valueChanges.pipe), затем асинхронный канал подписывается на эту новую ссылку, и автозаполнение устанавливается в этот статический список и следовательно, фильтрация не работает.

Однако, если мы не инициализируем его в функции подписки, this.tours будет пустым при вызове valueChanges.pipe(startWith('')) и, следовательно, список пуст для начала.

Таким образом, решение может состоять в том, чтобы инициализировать FilterOptions с помощью valueChanges.pipe () после заполнения this.tours (то есть внутри функции подписки).

...