Использование `combineLatest` с таблицей материалов Angular

Пытаюсь использовать combineLatest с угловым материалом Table. Попытка объединить MatPaginator и MatSort не работает.

Вот пример, которому я следую. Я смотрю на пример «Таблица, извлекающая данные через HTTP».

Вот что я пытаюсь сделать:

@ViewChild(MatPaginator) private _paginator: MatPaginator;
@ViewChild(MatSort) private _sort: MatSort;

public ngOnInit(): void {

    this._sort.sortChange.subscribe(
        () => {
            console.log("this works");
        }
    );

    combineLatest(
        this._sort.sortChange,
        this._paginator.page
    ).pipe(
        startWith({}),
        switchMap(
            () => {
                return this._userService.getAll();
            }
        ),
        tap(
            (users: IUser[]) => {
                this._data = users;
            }
        )
    ).subscribe();
}

Проблема с приведенным выше кодом заключается в том, что наблюдаемый объект combineLatest запускается только один раз при загрузке компонента. Я ожидаю, что он будет срабатывать каждый раз, когда запускается сортировка или разбиение на страницы. Когда я подписываюсь прямо на sortChange, он срабатывает каждый раз, когда я меняю сортировку.

Приведенный выше код будет работать, когда я изменю combineLatest на merge. Он будет работать так, как ожидалось. Но мне нужно объединять последние результаты как сортировщика, так и пагинатора каждый раз, когда какой-либо из них изменяется. Но он никогда не сработает с combineLatest. Что здесь происходит?


person prolink007    schedule 03.08.2018    source источник


Ответы (1)


Вы передаете результат combineLatest оператору startWith, который будет испускать только один раз. Просто исключите оператор startWith и вместо установки результата в операторе tap используйте функцию subscribe, например:

@ViewChild(MatPaginator) private _paginator: MatPaginator;
@ViewChild(MatSort) private _sort: MatSort;

public ngOnInit(): void {

    this._sort.sortChange.subscribe(
        () => {
            console.log("this works");
        }
    );

    merge(combineLatest(
        this._sort.sortChange,
        this._paginator.page), of({}))
    .pipe(switchMap(() => this._userService.getAll()))
    .subscribe((users: IUser[]) => this._data = users);
}
person ggradnig    schedule 03.08.2018
comment
Это не помогает. У меня там был startsWith, поэтому он сработает один раз, как только будет вызван ngOnInit. Таким образом, он вызовет функцию userService. И перемещение остальных вещей из tap на самом деле ничем не отличается от того, что делает для меня subscribe. Я попробовал ваше предложение, и оно не работает. sortChange и paginator не срабатывают внутри наблюдаемого combineLatest. Но он срабатывает при использовании merge и в наблюдаемом sortChange над кодом. - person prolink007; 03.08.2018
comment
Вы уверены, что этот paginator когда-либо срабатывает? combLatest будет испускать только в первый раз, когда по крайней мере обе наблюдаемые сработают хотя бы один раз. - person ggradnig; 03.08.2018
comment
Я также обновлю свой пост, чтобы включить требование для первого запуска при инициализации. - person ggradnig; 03.08.2018
comment
Я только что добавил startsWith({}) к _sort и _paginator, и теперь это работает. - person prolink007; 03.08.2018