primeng TurboTable (p-table) 在 scrollHeight='100%' 时无法正常工作
primeng TurboTable (p-table) does not work properly with scrollHeight='100%'
我想让 TurboTable 占据整个父级的高度(并在调整父级大小时调整大小),所以只有 table 的内容是可滚动的,并且没有滚动条添加到父级组件。
我试过设置 scrollHeight="100%",但没有按预期工作:https://stackblitz.com/edit/angular-d9narm.
有什么想法吗?
更新:正如@phucnh 更正的那样,我应该使用 scrollHeight="calc(100% - 200px)" 来补偿我的填充。我现在更新了我的 stackblitz 以反映这一点。这在 window 首次加载时非常有效,但如果您尝试更改它的高度,table 的高度将不会改变。
在CSS中,你设置了padding: 100px
所以你需要设置scrollHeight="calc(100% - 200px)"
如果你想在调整大小时更新高度,你需要处理更多。我建议一个演示
here
因此,在@phucnh 的一些帮助和一些谷歌搜索之后,我能够生成允许 TurboTable 正确获取其所有 parent 大小和 show/hide 滚动条的代码:
https://stackblitz.com/edit/primeng-scrollable-table-fit-parent
基本上,它包含两个技巧:
1)我们需要观察parent大小的变化,通过这段代码强制Angular到re-evaluate"scrollHeight":
ngAfterViewInit(): void {
new ResizeObserver(() => this.zone.run(() => this.onResize()))
.observe(this.container.nativeElement);
}
private onResize(): void {
// HACK: mark "scrollHeight" dirty, so it's re-evaluated.
if (this.table.scrollHeight.endsWith(' ')) {
this.table.scrollHeight = this.table.scrollHeight.slice(0, -1);
} else {
this.table.scrollHeight += ' ';
}
}
2) 为了解决 header 单元格在滚动条 appears/disappears 时变得不对齐的问题,我们需要做一些肮脏的黑客攻击(受 https://stackblitz.com/edit/primeng-dynamic-scrollable 启发):
// HACK: automatically re-align table header when resized. Borrowed the idea from https://stackblitz.com/edit/primeng-dynamic-scrollable
const scrollableViewNgAfterViewInit = ScrollableView.prototype.ngAfterViewInit;
ScrollableView.prototype.ngAfterViewInit = function() {
scrollableViewNgAfterViewInit.call(this);
new ResizeObserver(() => {
this.alignScrollBar();
}).observe(this.scrollBodyViewChild.nativeElement);
};
成功了。
更新(2020 年 6 月 6 日):
最近,此解决方法的第 2 部分停止工作。我假设发生这种情况是因为 Angular 现在缓存指向 life-cycle 事件的指针。因此,覆盖它们不会执行任何操作,并且不会触发覆盖的方法。
// HACK: automatically re-align table header when resized. Borrowed the idea from https://stackblitz.com/edit/primeng-dynamic-scrollable
const bindEventsOriginal = ScrollableView.prototype.bindEvents;
ScrollableView.prototype.bindEvents = function (): void {
bindEventsOriginal.call(this);
new ResizeObserver(() => {
this.alignScrollBar();
}).observe(this.scrollBodyViewChild.nativeElement);
};
此外,PrimeNG 9.1.0 版添加了 scrollHeight="flex",这实际上使得此解决方法的第 1 部分变得不必要。
turboTable 组件有问题。
这两个 hack 解决了这个问题,但它们只在 Chrome 中有效。我尝试在 Firefox 和 Edge 中使用它,两个浏览器都卡住了。我想是因为ResizeObserver是目前这两个浏览器不支持的特性。
我想让 TurboTable 占据整个父级的高度(并在调整父级大小时调整大小),所以只有 table 的内容是可滚动的,并且没有滚动条添加到父级组件。
我试过设置 scrollHeight="100%",但没有按预期工作:https://stackblitz.com/edit/angular-d9narm.
有什么想法吗?
更新:正如@phucnh 更正的那样,我应该使用 scrollHeight="calc(100% - 200px)" 来补偿我的填充。我现在更新了我的 stackblitz 以反映这一点。这在 window 首次加载时非常有效,但如果您尝试更改它的高度,table 的高度将不会改变。
在CSS中,你设置了padding: 100px
所以你需要设置scrollHeight="calc(100% - 200px)"
如果你想在调整大小时更新高度,你需要处理更多。我建议一个演示 here
因此,在@phucnh 的一些帮助和一些谷歌搜索之后,我能够生成允许 TurboTable 正确获取其所有 parent 大小和 show/hide 滚动条的代码:
https://stackblitz.com/edit/primeng-scrollable-table-fit-parent
基本上,它包含两个技巧:
1)我们需要观察parent大小的变化,通过这段代码强制Angular到re-evaluate"scrollHeight":
ngAfterViewInit(): void {
new ResizeObserver(() => this.zone.run(() => this.onResize()))
.observe(this.container.nativeElement);
}
private onResize(): void {
// HACK: mark "scrollHeight" dirty, so it's re-evaluated.
if (this.table.scrollHeight.endsWith(' ')) {
this.table.scrollHeight = this.table.scrollHeight.slice(0, -1);
} else {
this.table.scrollHeight += ' ';
}
}
2) 为了解决 header 单元格在滚动条 appears/disappears 时变得不对齐的问题,我们需要做一些肮脏的黑客攻击(受 https://stackblitz.com/edit/primeng-dynamic-scrollable 启发):
// HACK: automatically re-align table header when resized. Borrowed the idea from https://stackblitz.com/edit/primeng-dynamic-scrollable
const scrollableViewNgAfterViewInit = ScrollableView.prototype.ngAfterViewInit;
ScrollableView.prototype.ngAfterViewInit = function() {
scrollableViewNgAfterViewInit.call(this);
new ResizeObserver(() => {
this.alignScrollBar();
}).observe(this.scrollBodyViewChild.nativeElement);
};
成功了。
更新(2020 年 6 月 6 日):
最近,此解决方法的第 2 部分停止工作。我假设发生这种情况是因为 Angular 现在缓存指向 life-cycle 事件的指针。因此,覆盖它们不会执行任何操作,并且不会触发覆盖的方法。
// HACK: automatically re-align table header when resized. Borrowed the idea from https://stackblitz.com/edit/primeng-dynamic-scrollable
const bindEventsOriginal = ScrollableView.prototype.bindEvents;
ScrollableView.prototype.bindEvents = function (): void {
bindEventsOriginal.call(this);
new ResizeObserver(() => {
this.alignScrollBar();
}).observe(this.scrollBodyViewChild.nativeElement);
};
此外,PrimeNG 9.1.0 版添加了 scrollHeight="flex",这实际上使得此解决方法的第 1 部分变得不必要。
turboTable 组件有问题。
这两个 hack 解决了这个问题,但它们只在 Chrome 中有效。我尝试在 Firefox 和 Edge 中使用它,两个浏览器都卡住了。我想是因为ResizeObserver是目前这两个浏览器不支持的特性。