angular - 使用 rxjs 进行 Mat-sort 无法正常工作
问题描述
当从观察者流创建源时,我在 mat-table 中实现 mat-sort 时遇到问题。
只需通过以下文档实现它:
ngAfterViewInit() {
this.dataSource.sort = this.sort;
}
无法正常工作 - 我的桌子上总是只排序 5 行。
我认为,我的问题在于正确使用它与 rxjs 连接。
不幸的是,在检查了另一个问题/文档后,我找不到任何想法。
我从两个观察者流生成数据源。我还使用了 BehaviourSubject(用于初始值)、combineLatest 和 switch map。表已正确创建并且工作正常。
此外,当我添加过滤器(根据角度材料设计文档)时,它工作正常。但是垫排序......不是(只有5个第一行)。
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));
}
我也尝试过使用 Observable.zip - 但我认为这也不是我的情况。任何想法/建议都将非常有价值。
我认为,我应该订阅可观察流的排序方法。我在分页时遇到了同样的问题。有时有效,有时无效。
解决方案
您的问题代码类似于显示来自 HTTP 调用的数据的 mat-tables 示例:https ://stackblitz.com/angular/rmoxkmpkkyj?file=app%2Ftable-http-example.ts
我认为可以通过分别处理分页和排序事件来简化实现。
请看一下我构建的这个示例,它刷新每个事件的数据:https ://stackblitz.com/edit/angular-material-mat-table-sort-merge-streams?file=src%2Fapp%2Fmy-books %2Fmy-books.component.ts
事件处理程序
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());
});
}
获取当前视图选项的方法
getCurrentOptions() {
const options: ViewOptions = {
sortField: this.sort.active,
sortDirection: this.sort.direction,
page: this.paginator.pageIndex,
pageSize: this.paginator.pageSize
};
return options;
}
如何合并多个流的示例
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;
}
推荐阅读
- javascript - 如何在我的 webpack 项目中使用 require.context?
- bson - LiteDB BsonExpression:是否有任何方法返回 true?
- c# - 带有尾随“。”的 WPF DependencyProperty 问题。
- python - 为什么使用 python stripe lib 检索时,条带费用不显示为“已退款”?
- java - 如何在 Android 模拟器中手动选择纬度和经度,而不是选择地图上的点,
- sql - 如何在 SQL Server 的 BINARY 或 VARBINARY 变量中设置特定位?
- r - 如何提取向量变量的第一行
- javascript - WordPress 无法识别自定义 JS?
- javascript - 当使用 PHP 插入更多条目时,如何控制 Chart.js 中 Y 轴值的覆盖?
- python - 包含黑色代码格式化程序行长忽略注释