由Google推出的Material Design,在Angular世界的实现也是由Angular 团队实现和维护的https://github.com/angular/componentshttps://github.com/angular/componentsAngular Material UI component libraryUI component infrastructure and Material Design components for mobile and desktop Angular web applications.
https://material.angular.io/
但是,它并不完善,比如今天要说的虚拟化,或者叫Virtual Scroll,官方给出的解决办法是"cdk-virtual-scroll-viewport",他会创建一个wrapper来包裹实际滚动的界面部分,和一个spacer来撑大整个viewport的区域,告诉滚动条,实际数据有多长。
整个设计很巧妙的使用了“position: absolute” 这个特性,保证spacer老实的躺在旁边当标尺,而wrapper可以丝滑的在spacer旁边滚动,这样就不需要加载全部数据,而是根据你滚动的位置,动态的加载数据。
这时候就有一个矛盾是每一行的高度只能是固定的,否则viewport算不出来该显示哪些?但是Angular给出了自定义的方式:VirtualScrollStrategy,用户可以自定义自己的逻辑来确定哪些需要显示,而这个官方推荐了第三方的实现:
https://github.com/diprokon/ng-table-virtual-scrollhttps://github.com/diprokon/ng-table-virtual-scroll当滚动条滚动的时候,会触发
VirtualScrollStrategy
的onContentScroll方法,
(https://github.com/angular/components/blob/master/src/cdk/scrolling/virtual-scroll-viewport.ts)
在这个方法中,会去viewport中获取当前的scroll position,利用当前的位置和上一次的位置,判断滚动方向,以及是否需要加载新的数据刷新视图。
整个实现在普通的table中运行的非常良好,但是,当table变得复杂的时候,会出现上下不停跳的情况(比如当前几列固定位置,使用sticky属性时)。
这时,当VirtualScrollStrategy收到scroll通知时,它从viewport中获取的scroll position并不正确,例如,当你一直向下滚动时,会在中间穿插若干向上滚动的事件,由于Angular Material没有给滚动方向,只能单纯的凭借本地的scroll position和上次的对比来决定滚动方向,所以这个问题目前无法修复。只能寄希望于Angular团队修复他们的滚动的问题。
最后,仍然是推荐使用这个包,但是仅仅对于简单的table而言,对于复杂的table还是使用分页比较保险。