Как отфильтровать наблюдаемые для маршрутизации в Angular Material Autocomplete - PullRequest
0 голосов
/ 18 октября 2018

Я использую Angular Material "^ 6.4.7" и Angular "^ 6.1.9".Я сделал некоторую маршрутизацию для навигации по меню, заполненному наблюдаемыми (для навигации по идентификатору этих наблюдаемых).Теперь мне нужно добавить автозаполнение, чтобы отфильтровать это меню (чтобы помочь пользователю найти конкретную опцию), но у меня есть некоторые проблемы для достижения этой цели.

Мой html

    <mat-form-field>
        <mat-label>Find datasource...</mat-label>
        <input matInput name="datasource filter" [formControl]="searchForm" [ngModel]="dataSourceFilterInput">
    </mat-form-field>

    <div *ngFor="let datasource of dataSourceFiltered$ | async">
        <div [routerLink]="[datasource.id]">
            <h6>{{datasource.name}}</h6>
        </div>
    </div>

Мой ts:

export class DataSourceSelectorComponent implements OnInit {

dataSourceFiltered$: Observable<IDataSourceDefinition[]>;
dataSource$: Observable<IDataSourceDefinition[]>;
dataSourceList: IDataSourceDefinition[] = [];
searchForm: FormControl = new FormControl();

constructor(private _datasourceService: DataSourceConfigurationService, private _route: ActivatedRoute) {
}

ngOnInit() {
    this.dataSourceFiltered$ = this._route.paramMap.pipe(
        switchMap(params => {
            this.selectedId = +params.get("id");
            this.dataSource$ = this._datasourceService.getAllDataSources();
            this.dataSource$.subscribe(ds => (this.dataSourceList = ds));
            return this.dataSource$;
        })
    );
}

}

Где IDataSourceDefinition - мой интерфейс со свойством "name".

Я думаю, что внутри ngOnInit мне нужно добавить фильтр (как предложено в Angular Material с использованием элемента управления формы (в данном случае searchForm) и «valueChanges.pipe ()»), но все методы, такие как «map»"или" startWith "или" filter "нельзя использовать с Observables.

Я не могу просто отфильтровать подписку Observable, мне нужно, чтобы фильтр возвращал Observable, в противном случае маршрутизация будет нарушена.

Есть предложения?

1 Ответ

0 голосов
/ 19 октября 2018

Способ вызова операторов, например map или filter, изменился в RxJs 6, который используется Angular 6. Google найдет для вас множество руководств, которые объяснят все изменения, но это поможет вам начать.

Вы уже используете switchMap правильный путь, и вам нужно просто продолжать это делать.

В RxJs 5 вы бы вызывали операторов напрямую, например:

someObservable
  .map(item => doSomethingWith(item))
  .filter(item => isThisItemValid(item));

И так далее.

Начиная с RxJs 6, вы все их транслируете.Так что мой псевдокод выше превращается в:

someObservable
  .pipe(map(item => doSomethingWith(item)))
  .pipe(filter(item => isThisItemValid(item)));

Точно такой же код, просто оберните их в вызовы pipe.

Другое важное изменение - то, откуда вы их импортируете.Все операторы (может быть, только большинство?) Импортированы из rxjs/operators, поэтому для использования map, switchMap и filter вы должны включить это в начало вашего файла:

import { map, switchMap, filter } from 'rxjs/operators';

Я не знаю точно, что вы хотели сделать в своем примере кода, но вы можете просто добавить дополнительные pipe вызовы в конец того, что у вас есть:

ngOnInit() {
    this.dataSourceFiltered$ = this._route.paramMap.pipe(
        switchMap(params => {
            this.selectedId = +params.get("id");
            this.dataSource$ = this._datasourceService.getAllDataSources();
            this.dataSource$.subscribe(ds => (this.dataSourceList = ds));
            return this.dataSource$;
        })
    )
    .pipe(filter(item => filterItHere(item)))
    .pipe(map(item => mapItHere(item)));
}
...