我真的很想加入cdk-virtual-scroll。但是使用cdk-virtual-scroll时,表头将不会跟随CSS粘滞位置属性。所以我碰到了一篇描述自定义滚动策略的文章。
https://stackblitz.com/edit/cdk-virtual-table-sticky-header?file=src%2Fapp%2Fapp.component.ts
在此示例中,它们扩展了数据源。
这里有硬编码的数据。
rows = Array(200).fill(0).map((x, i) => {
return {name: 'name' + i, id: i, age: 27};
});
有没有一种方法可以从http调用中获取数据,并使用可观察的对象填充dataSource并使用模板中的异步管道将这些可观察的对象拆开。 (而不是对component.ts文件中的数据进行硬编码或订阅componenet.ts文件中的数据来实现上述自定义滚动)?
拨打http到此终点:
https://jsonplaceholder.typicode.com/users
赞:
[dataSource]="dataSource | async"
答案 0 :(得分:0)
该表通过调用dataSource.connect
从数据源中以Observable形式获取数据。此函数应返回一个Observable,该数据发出要显示的数据。使用数据源时,您不需要AsyncPipe。
将初始数据作为Observable传递到您的数据源,并在返回数据之前使用dataSource.connect
中的RxJS运算符修改此数据。在dataSource.disconnect
中终止Observable。
根据您提供的堆栈闪电,可能是:
const PAGESIZE = 20;
const ROW_HEIGHT = 48;
export class GridTableDataSource extends DataSource<any> {
private initialData$: Observable<any[]>;
private onDisconnect$ = new Subject<void>();
offset = 0;
offsetChange = new BehaviorSubject(0);
constructor(
initialData$: Observable<any[]>,
private viewport: CdkVirtualScrollViewport,
private itemSize: number
) {
super();
this.initialData$ = initialData$;
this.viewport.scrollToOffset(0);
}
connect(collectionViewer: CollectionViewer): Observable<any[] | ReadonlyArray<any>> {
return combineLatest( // combine the scroll events with your initial data
this.viewport.elementScrolled().pipe( // start with a currentTarget
startWith({ currentTarget: this.viewport.getElementRef().nativeElement })
),
this.initialData$.pipe(
tap(data => this.viewport.setTotalContentSize(this.itemSize * data.length))
)
).pipe(
map(([event, initialData]: [any, any[]]) => { // map to visible data
const start = Math.floor(event.currentTarget.scrollTop / ROW_HEIGHT);
const prevExtraData = start > 5 ? 5 : 0;
// const prevExtraData = 0;
const slicedData = initialData.slice(
start - prevExtraData,
start + (PAGESIZE - prevExtraData)
);
this.offset = ROW_HEIGHT * (start - prevExtraData);
this.viewport.setRenderedContentOffset(this.offset);
this.offsetChange.next(this.offset);
return slicedData;
}),
takeUntil(this.onDisconnect$) // unsubscribe on disconnect
);
}
disconnect(collectionViewer: CollectionViewer): void {
this.onDisconnect$.next();
}
}
将http请求作为初始数据传递到您的自定义数据源。
this.dataSource = new GridTableDataSource(
this.http.get<any[]>("https://jsonplaceholder.typicode.com/todos"),
this.viewport,
this.itemSize
);
https://stackblitz.com/edit/cdk-virtual-table-sticky-header-26g3j5