Primeng 使可滚动数据表高度响应

问题描述 投票:0回答:9

PrimeNG DataTable 提供了

[scrollable]
属性来定义垂直和/或水平滚动。这必须与一组
scrollHeight
和/或
scrollWidth
组合使用。

如何才能拥有一个可以适应窗口高度/宽度并保持可滚动功能的表格?

这是我尝试过的代码:

<div class="ui-g-12">

    <p-dataTable class="ui-g-12" [value]="rows"    [hidden]="this.apiService.spinnerIsVisible"
    [style]="{ height: 'fit-content', 'margin-top': '10px' }"
    [resizableColumns]="false" columnResizeMode="fit" emptyMessage="No records found"
    [responsive]="false"
    [globalFilter]="tableSearch"
    [editable]="true"
    [scrollable]="true" scrollHeight="100%" scrollWidth="100%">

      <p-header>
        <button pButton type="button" icon="fa-refresh" (click)="refresh()" style="float:left"></button>
        <label for="tableSearch">Global search: </label>
        <input id="tableSearch" #tableSearch type="text" placeholder="type here">
      </p-header>

      <p-column
        *ngFor="let col of cols" [header]="col" [field]="col"
        [style]="{'width': '250px', 'min-width': '50px', 'word-wrap': 'break-word'}"
        [sortable]="true"
        [filter]="true" filterPlaceholder="" filterMatchMode="contains"
        [editable]="true">
      </p-column>

    </p-dataTable>
</div>

但它只解决了响应宽度问题。在屏幕截图中,您可以看到可水平滚动的表格: here is the screenshot

由于在百分比值的情况下,

height
p-dataTable
属性是相对于父级的,因此我尝试通过将
div
添加到父级
style="height: 100%"
来使父级
div
适应内容。这是更新后的代码:

<div class="ui-g-12" style="height: 100%">

    <p-dataTable class="ui-g-12" [value]="rows" [hidden]="this.apiService.spinnerIsVisible"
    [style]="{ height: 'fit-content', 'margin-top': '10px' }"
    [resizableColumns]="false" columnResizeMode="fit" emptyMessage="No records found"
    [responsive]="false"
    [globalFilter]="tableSearch"
    [editable]="true"
    [scrollable]="true" scrollHeight="100%" scrollWidth="100%">

      <p-header>
        <button pButton type="button" icon="fa-refresh" (click)="refresh()" style="float:left"></button>
        <label for="tableSearch">Global search: </label>
        <input id="tableSearch" #tableSearch type="text" placeholder="type here">
      </p-header>

      <p-column
        *ngFor="let col of cols" [header]="col" [field]="col"
        [style]="{'width': '250px', 'min-width': '50px', 'word-wrap': 'break-word'}"
        [sortable]="true"
        [filter]="true" filterPlaceholder="" filterMatchMode="contains"
        [editable]="true">
      </p-column>

    </p-dataTable>
</div>

我还对我的

styles.scss
文件进行了以下更改以使其正常工作(在 stackoverflow 上的其他一些问题中发现了这一点):

html, body {
  height: 100%;
}

但这对我来说也不起作用:enter image description here 在屏幕截图上,高度似乎是正确的,但事实并非如此。当我向下滚动时,首先,它会按预期进行,但是当接近表格末尾时,滚动条会从视图中出来,所以当我仍然能够滚动时我看不到它。所以看起来数据表比应有的要高一点。

那么我该如何解决这个问题呢?任何帮助将不胜感激!

css angular primeng primeng-datatable
9个回答
24
投票

我在

p-table
使用这个(不确定是否适用于
p-datatable
)。


[scrollHeight]="'calc(100vh - 204px)'"


15
投票

我不知道这是否完全适合您的情况,但我通过将scrollHeight数据表属性设置为解决了我的问题:

scrollHeight="50vh"

vh指的是:

vh 相对于视口

高度的1%

视口 = 浏览器窗口大小。如果视口宽 50 厘米,则 1vw = 0.5 厘米。

您可以测试 vh 的不同值,看看哪个更适合。

更多关于: https://www.w3schools.com/cssref/css_units.asp


8
投票

Prime NG 表引入了用于视口高度调整的 Flex 模式

scrollHeight="flex"

它将占据父元素的完整高度。


2
投票

我的故事:

从9.1.0版本开始,组件会根据窗口的大小自动重建。但就我而言,窗口大小没有变化,但 dom 树发生了变化,因为附加元素被删除了。

我的解决方案:

scrollHeight='flex';

这对我没有帮助,因为我有一个与滚动相关的特定分页,最后我只是在更改 dom 时额外调用了调整大小事件。

setTimeout(() => window.dispatchEvent(new Event('resize')));

1
投票

您可以在 ts 文件中获取内部高度和内部宽度,例如

setInnerWidthHeightParameters()
  {
    this.innerWidth = window.innerWidth;
    this.innerHeight = window.innerHeight * 0.70;
  }

并将其用作

[scrollHeight]="innerHeight +'px'"

动态设置它,它对我有用。


1
投票

对于其他搜索类似问题的人,我这样解决它们:

  1. 在模板中标记 PARENT div(例如)#leftSidebar

  2. 在组件中使用视图子项:

    @ViewChild('leftSidebar', { static: true }) leftSidebar: ElementRef;

  3. 您可以访问它并获取位置和大小,如下所示:

    让矩形:any = this.leftSidebar.nativeElement.getBoundingClientRect(); 让 x: number = rect.x; 让 y: 数字 = 矩形.y; 让宽度:数字=矩形宽度; 让高度:数字= rect.height;

  4. 你可以像上面描述的Arthur那样设置:

    [scrollHeight]="高度+'px'"


0
投票

ScrollHeight 需要为 100%。


0
投票

我通过这个解决方案实现了什么:

  1. 桌子的动态高度取决于可用空间
  2. 如果表格的条目超出可用高度,表格将显示滚动条,用户可以在表格组件内滚动。

步骤

  1. 确保直接父级无法扩展。要么设置一个恒定的高度,要么使用“flex”和“overflow:hidden”(或者我不知道的东西)。
  2. 将“display : flex”添加到父级
  3. 添加以下 html 和 css。

html:

<p-table scrollable="true"
         scrollHeight="flex"
         ...>
...
</p-table>

CSS:

p-table {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    overflow: hidden;
}

::ng-deep .p-datatable.p-component.p-datatable-hoverable-rows.p-datatable-scrollable.p-datatable-flex-scrollable {
    flex: 1 1 auto;
    min-width: 100%;
    max-width: 100%;
    min-height: 100%;
    max-height: 100%;
}

希望这有帮助。


0
投票

我刚刚花了一整个上午想出一个通用的指令。我只需要可滚动的高度,但这也应该适用于水平滚动。

table-scroll-height.directive.ts

@Directive({
  selector: 'p-table' // you may want more specificity
})
export class TableScrollHeightDirective {

  // Injected
  readonly injector = inject(Injector);
  readonly changeDetectorRef = inject(ChangeDetectorRef);
  readonly destroyRef = inject(DestroyRef);

  // Constants
  readonly table = inject(Table, { self: true, host: true });

  // Computed
  readonly $elementResize = this.$getElementResize(this, (this.table.el.nativeElement as HTMLElement).parentElement!);

  // Effects
  constructor() {
    this.maintainScrollHeight();
  }

  // Private methods

  private maintainScrollHeight() {
    const table = this.table;
    table.scrollHeight = `0px`;
    const element = table.el.nativeElement as HTMLElement;
    const throwError = () => { throw new Error('Table must be wrapped inside an element with no other children and given a position of relative'); }
    if (element.parentElement?.children.length !== 1) throwError();
    setTimeout(() => getComputedStyle(element.parentElement!).position !== 'relative' ?? throwError())
    element.style.flex = '1';
    element.style.position = 'absolute';
    element.style.top = '0';
    element.style.right = '0';
    element.style.bottom = '0';
    element.style.left = '0';
    effect(() => {
      const size = this.$elementResize();
      table.scrollHeight = `${size.height}px`;
      this.changeDetectorRef.detectChanges();
    });
  }


  $getElementResize(context: { injector: Injector }, element: HTMLElement) {
    const destroyRef = context.injector.get(DestroyRef);
    const $result = signal(element.getBoundingClientRect());
    const resizeObserver = new ResizeObserver((entries) => {
      for (const entry of entries) {
        setTimeout(() => $result.set(entry.contentRect));
      }
    });
    resizeObserver.observe(element);
    destroyRef.onDestroy(() => resizeObserver.disconnect());
    return $result;
  }
}

app.module.ts

@NgModule({
  declarations: [TableScrollHeightDirective],
  exports: [TableScrollHeightDirective]
})
export class TableScrollHeightModule { }

导入模块

@NgModule({
  imports: [
    TableScrollHeightModule,
  ],
})
export default class AppModule {}

然后,在您的组件模板中:

<div class="table-wrapper">
  <p-table [scrollable]="true">
</div>

最后,在你的组件样式中

.table-wrapper {
  position: relative;
}
© www.soinside.com 2019 - 2024. All rights reserved.