Mat-sort avec rxjs ne fonctionne pas correctement
j'ai le problème avec l'implémentation mat-sort dans mat-table, quand la source a été créée à partir de observers stream.
Simplement de la mise en œuvre par l'intermédiaire de la documentation par:
ngAfterViewInit() {
this.dataSource.sort = this.sort;
}
ne fonctionne pas correctement - sera toujours triés seulement 5 lignes sur ma table.
je pense, mon problème est avec l'utilisation correcte avec la connexion rxjs.
malheureusement, après avoir vérifié une autre question / documentation Je ne trouve aucune idée.
j'ai généré les données source: flux de deux observateurs. J'ai aussi utilisé pour It BehaviourSubject (pour les valeurs initiales), combineLatest et switch map. Tableau a été créé correctement et fonctionne parfaitement.
<!-Aussi quand j'ai ajouté le filtre (selon la documentation de conception du matériau angulaire) fonctionne correctement. Mais des tapis de tri... pas (seulement 5 premières lignes).ngOnInit() {
this.filters = itemFilters;
this.idSubject = new BehaviorSubject(this.filters[0]);
Observable.combineLatest(this.name, this.selectedFilter)
.do(_ => this.items = null)
.switchMap(([name, filterIndex]: [Name | null, number]) => {
const item = this.filters[filterIndex];
this.namesSubject.next(item.display);
return this.itemService.getItems(name);
})
.subscribe(this.setItems.bind(this), this.setError.bind(this));
}
J'ai aussi essayé avec Observable.zip - mais je pense que c'est pas mon cas. Toute idée / Conseil sera très précieux.
je pense, je devrait souscrire la méthode de tri aux flux observables. Même problème que j'ai avec la pagination. Parfois fonctionne, parfois pas.
1 réponses
votre code de question ressemble à l'exemple des tables mat qui affichent les données des appels HTTP: https://stackblitz.com/angular/rmoxkmpkkyj?file=app%2Ftable-http-example.ts
je pense que l'implémentation peut être simplifiée en traitant la pagination et en triant les événements séparément.
veuillez jeter un coup d'oeil à cet exemple I build qui rafraîchit les données sur chaque événement: https://stackblitz.com/edit/angular-material-mat-table-sort-merge-streams?file=src%2Fapp%2Fmy-books%2Fmy-books.component.ts
Les gestionnaires d'Événements
ngOnInit() {
// default data
this.refresh(this.getDefaultOptions());
this.sort.sortChange.subscribe((sort: Sort) => {
console.log('sortChange', this.sort.active);
this.paginator.pageIndex = 0;
this.refresh(this.getCurrentOptions());
});
this.paginator.page.subscribe((page: PageEvent) => {
console.log('paginator ', page);
this.refresh(this.getCurrentOptions());
});
}
La méthode pour récupérer les options d'affichage
getCurrentOptions() {
const options: ViewOptions = {
sortField: this.sort.active,
sortDirection: this.sort.direction,
page: this.paginator.pageIndex,
pageSize: this.paginator.pageSize
};
return options;
}
Un exemple de comment fusionner plusieurs flux
findBooks(options: ViewOptions): Observable<BooksResponse> {
console.log('findBooks', options);
// retrieve multiple streams
const multipleStreams = this.mockMultipleStreams();
// sort and slice result
const sortedAndSliced = multipleStreams.pipe(
tap(items => {
items = items.sort((a, b) => {
const sortOrder = options.sortDirection === 'asc' ? -1 : 1;
const valueA = a[options.sortField];
const valueB = b[options.sortField];
var result = (valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0;
return result * sortOrder;
});
}),
tap((items: Book[]) => {
const start = options.page * options.pageSize;
const end = start + options.pageSize;
items = items.slice(start, end);
})
);
// wrap in the response object
const bookResponse = sortedAndSliced.pipe(
map((items: Book[]) => {
const response: BooksResponse = {
items: items,
total: this.fakeDataLength
};
return response;
})
);
return bookResponse;
}
mockMultipleStreams(): Observable<Book[]> {
const third = this.fakeDataLength / 3;
// merge all the streams together
const allTheBooks: Observable<[Book[], Book[], Book[]]> = zip(
of(this.mockBooks('Magazine', third)),
of(this.mockBooks('Books', third)),
of(this.mockBooks('Newspaper', third))
);
// flatten the data
const result = allTheBooks
.pipe(map((items) => {
let result: Book[] = [];
items.forEach(books => {
books.forEach(book => { result.push(book) })
});
return result;
}));
return result;
}
Voir le code complet ici: https://stackblitz.com/edit/angular-material-mat-table-sort-merge-streams?file=src%2Fapp%2Fbooks.service.ts