PrimeNG懒加载表格在应用筛选时覆盖了’first’属性。

huangapple go评论71阅读模式
英文:

PrimeNG lazy table override 'first' attribute whenever applying filtering

问题

我正在尝试使用queryParameters来初始化一个primeNG表格。例如,http://my-url.com/table?name=Joe&first=20 应该显示名为Joe的数据,从第20个条目开始。

该表格使用 `[lazy]=true` 进行懒加载,因为后端提供的数据量非常大。当我初始化我的组件时,我读取URL参数来应用过滤和分页。

my-component.html
```html
<p-table
  [paginator]="true"
  [lazy]="true"
  (onLazyLoad)="onLazyLoad($event)"
  [lazyLoadOnInit]="false"
  [(first)]="firstItem"
> <!-- ... -->

my-component.ts

export class MyComponent {
  @ViewChild('tableElement', {static: true}) pTableRef!: Table;

  protected firstItem = 0;

  ngOnInit(): void {
    this.route?.queryParamMap.pipe(first()).subscribe({
      next: (paramMap) => this.initStateFromParamMap(paramMap)
    });
  }

  ngAfterViewInit(): void {
    console.log("ngAfterViewInit called, this.firstItem = " + this.firstItem)
    // 如果未进行过滤操作,手动使用虚拟参数调用onLazyLoad。
    // 如果进行了过滤操作,p-table会自动调用onLazyLoad
  }

  private initStateFromParamMap(paramMap: ParamMap) {
    // 注意:此代码只是对实际操作的简化
    this.lazyLoadingDoneAtLeastOnce = true;
    this.firstItem = firstItem;
    this.pTableRef.filter("Joe", name, 'equals');
    console.log("init finished, this.firstItem = " + this.firstItem)
  }

  onLazyLoad(event: LazyLoadEvent) {
    console.log("onLazyLoad called, this.firstItem = " + this.firstItem)
    // 从后端加载指定的数据
  }
}

输出:

init finished, this.firstItem = 20
ngAfterViewInit called, this.firstItem = 20
onLazyLoad called, this.firstItem = 0

调用 this.pTableRef.filter("Joe", name, 'equals'); 会导致将 firstItem 设置为零,这是用户决定手动应用过滤时的基本行为。但是,在这种情况下,我不想重置 firstItem

备注:

  • 交换过滤初始化和分页初始化顺序不会改变任何内容。
  • 如果未进行过滤操作,ngAfterViewInitthis.firstItem 不会更改。
  • 为了可读性,省略了我的代码中的许多无关元素。

<details>
<summary>英文:</summary>

I am trying to initialize a primeNG table using queryParameters. e.g. http://my-url.com/table?name=Joe&amp;first=20 should display data with name Joe, beginning at the 20th entry

That table use lazyLoading with `[lazy]=true` because of the sheer amount of data my backend can provides. When I initialize my component I read url parameters to apply filtering and pagination.

my-component.html

<p-table
[paginator]="true"
[lazy]="true"
(onLazyLoad)="onLazyLoad($event)"
[lazyLoadOnInit]="false"
[(first)]="firstItem"
> <!-- ... -->

my-component.ts

export class MyComponent {
@ViewChild('tableElement', {static: true}) pTableRef!: Table;

protected firstItem = 0;

ngOnInit(): void {
this.route?.queryParamMap.pipe(first()).subscribe({
next: (paramMap) => this.initStateFromParamMap(paramMap)
});
}

ngAfterViewInit(): void {
console.log("ngAfterViewInit called, this.firstItem = " + this.firstItem)
// manually call onLazyLoad with dummy parameters if no filtering is done.
// if filtering is done, p-table automatically calls onLazyLoad
}

private initStateFromParamMap(paramMap: ParamMap) {
// note : this code is a just simplification of what is done
this.lazyLoadingDoneAtLeastOnce = true;
this.firstItem = firstItem;
this.pTableRef.filter("Joe", name, 'equals');
console.log("init finished, this.firstItem = " + this.firstItem)
}

onLazyLoad(event: LazyLoadEvent) {
console.log("onLazyLoad called, this.firstItem = " + this.firstItem)
// load specified data from backend
}
}

output:

init finished, this.firstItem = 20
ngAfterViewInit called, this.firstItem = 20
onLazyLoad called, this.firstItem = 0

Calling `this.pTableRef.filter(&quot;Joe&quot;, name, &#39;equals&#39;);` result in firstItem being set to zero, this is the basic behaviour if the user decides to manually apply a filter. However I do not want to reset the firstItem in this case.

Notes: 
- Swapping filter initialization and pagination initialization order does not change anything.
- If no filtering is done. `this.firstItem` is not changed after `ngAfterViewInit`
- Many unrelated element of my code have been omitted for readability

</details>


# 答案1
**得分**: 0

在查看PrimeNG Table源代码时,我发现了一个名为`restoringFilter`的布尔属性,如果将其设置为true,下一次过滤将不会重置第一项。

顺便说一下,调用`filters`会触发超时过滤,这就是为什么连续进行多次过滤不会触发多次调用`onLazyLoad`的原因,这也是过滤(因此重新初始化第一项为0...)在ngAfterViewInit之后进行的原因。

简而言之,当恢复过滤时,请将`restoringFilter`设置为true

```javascript
this.pTableRef.restoringFilter = true;
this.pTableRef.filter("Joe", name, 'equals');

现在这个功能完美运行。

英文:

Looking through PrimeNG Table source code, I've found a boolean attribute named restoringFilter, if this is set to true, next filtering won't reset first item.

By the way, calling filters trigger a timed out filtering, this is why multiples filtering done sequentially do not trigger multiple call to onLazyLoad, this is the same reason filtering (and therefore reinitialization of first item to 0...) was done after ngAfterViewInit.

TL;DR, set restoringFilter to true when restoring filters

this.pTableRef.restoringFilter = true;  
this.pTableRef.filter(&quot;Joe&quot;, name, &#39;equals&#39;);

This now works perfectly.

huangapple
  • 本文由 发表于 2023年5月24日 23:21:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76325105.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定