J'ai le problème d'implémenter mat-sort dans mat-table, lorsque la source a été créée à partir du flux d'observateurs.
Il suffit de le mettre en œuvre via la documentation en:
ngAfterViewInit() {
this.dataSource.sort = this.sort;
}
ne fonctionne pas correctement - seront toujours triés que 5 lignes sur ma table.
Je pense, mon problème est avec la bonne utilisation avec la connexion rxjs.
Malheureusement, après avoir vérifié d'autres questions/documentation, je ne trouve aucune idée.
J'ai généré une source de données à partir de deux flux d'observateurs. J'ai aussi utilisé pour cela BehaviourSubject (pour les valeurs initiales), combineLatest et switch map. La table a été créée correctement et fonctionne parfaitement.
De plus, lorsque j'ai ajouté le filtre (selon la documentation de conception du matériau angulaire), il fonctionne correctement. Mais mat-sort ... 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 ce n'est pas non plus mon cas. Toute idée/conseil sera très précieux.
Je pense que je devrais souscrire la méthode de tri aux flux observables. Le même problème que j'ai avec la pagination. Parfois, fonctionne, parfois pas.
Votre code de question ressemble à l'exemple de mat-tables qui affiche les données d'appels HTTP: https://stackblitz.com/angular/rmoxkmpkkyj?file=app%2Ftable-http-example.ts
Je pense que l'implémentation peut être simplifiée en gérant les événements de pagination et de tri séparément.
Veuillez regarder cet exemple que je construis 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 obtenir les options d'affichage en cours
getCurrentOptions() {
const options: ViewOptions = {
sortField: this.sort.active,
sortDirection: this.sort.direction,
page: this.paginator.pageIndex,
pageSize: this.paginator.pageSize
};
return options;
}
Exemple de fusion de 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