【问题标题】:Angular Material Table with Selection Model and server side pagination带有选择模型和服务器端分页的角材料表
【发布时间】:2022-06-15 02:37:21
【问题描述】:

我有一个 Angular Material table 和一个 pagination 和一个 selection model 来获取一些行来做事。 目前我正在用server-side pagination 更改pagination,但是这样我的选择模型就坏了。当我更改页面时,我可以向选择模型添加行,并且工作正常。但是当我返回上一页时,行(在选择模型中)没有显示为选中状态。

我的选择模型,方法和angular material的demo page中发布的方法一样:

  selection = new SelectionModel<ItemManagementViewDTO>(true, []);

  isAllSelected(): boolean {
    const numSelected = this.selection.selected?.length;
    const numRows = this.items?.length;
    return numSelected === numRows;
  }
 

  masterToggle(): void {
    this.isAllSelected() ? this.selection.clear() : this.items?.forEach(row => this.selection.select(row));
  }

  checkboxLabel(row?: ItemManagementViewDTO): string {
    if (!row) {
      return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
    }
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.idItem + 1}`;
  }

html 很简单:

  <table mat-table [dataSource]="items" class="mat-elevation-z8" matSort>
        <!-- Checkbox Column -->
        <ng-container matColumnDef="select">
          <th mat-header-cell *matHeaderCellDef>
            <mat-checkbox
              (change)="$event ? masterToggle() : null"
              [checked]="selection.hasValue() && isAllSelected()"
              [indeterminate]="selection.hasValue() && !isAllSelected()"
              [aria-label]="checkboxLabel()"
              color="primary"
            >
            </mat-checkbox>
          </th>
          <td mat-cell *matCellDef="let row">
            <mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? selection.toggle(row) : null" [checked]="selection.isSelected(row)" [aria-label]="checkboxLabel(row)" color="primary">
            </mat-checkbox>
          </td>
        </ng-container>
<!-- ... -->
<mat-paginator [length]="totalItems" (page)="onPageChange($event)" [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>

我的OnPageChangeserver-side 的分页是:

  onPageChange(event: PageEvent): void {
    this.itemsServ.getPaginatedItems(this.paramsStored, event.pageIndex, event.pageSize).subscribe(r => {
      this.items = r.listDTO;
      this.totalItems = r.totalElements;
  }

我错过了什么?每次更改页面时,都会刷新源,但该项目仍然存在于选择模型中(如果我添加了它)。如果它与上一次调用中的项目相同,为什么它不会显示为选中?

提前致谢!

【问题讨论】:

    标签: angular angular-material pagination


    【解决方案1】:

    SelectionModel 在内部使用 Set 来存储所有选定的元素。

    SelectionModel.isSelected 方法使用 Set.has 方法,该方法返回一个布尔值,指示元素是否存在于 Set 中。

    下面是一个示例,如果您将 Set.has 与不同的对象引用一起使用会发生什么。

    var set1 = new Set();
    var obj1 = {'key1': 1};
    set1.add(obj1);
    
    set1.has(obj1);        // returns true
    set1.has({'key1': 1}); // returns false because they are different object references
    

    在您的情况下,如果您来回切换,表具有相同的数据但不同的引用。

    一种解决方案是用新项目替换/删除所选项目。

    onPageChange(event: PageEvent): void {
         this.itemsServ.getPaginatedItems(this.paramsStored, event.pageIndex, event.pageSize).subscribe(r => {
         this.items = r.listDTO;
         // replace old selected items with new ones
         const itemsToAdd= items.
               filter(item=> {
                  const foundItem = this.selection.selected.find(selectedItem=> selectedItem.id === item.id);
                  if(!foundItem) return;
                  // removes item from selection
                  this.selection.deselect(foundItem);
                  return item;
               });
          
         this.selection.select(itemsToAdd);
         this.totalItems = r.totalElements;
    

    }

    【讨论】:

      【解决方案2】:

      我也有同样的问题。我还没有检查接受的答案是否有效,但这里有一个更干净的选择。

      首先,编写一个新方法来确定是否检查了一行。这将用于覆盖 SelectionModel 的比较方法:

      isChecked(row: any): boolean {
          const found = this.selection.selected.find(el => el._id === row._id);
          if (found) {
            return true;
          }
          return false;
       }
      

      然后在您的 ngOnInit 中,告诉 SelectionModel 使用您的新方法进行比较。

      this.selection.isSelected = this.isChecked.bind(this);
      

      使用此方法,您根本不需要替换选择集中的对象。

      (来源:https://github.com/angular/components/issues/9670#issuecomment-455117080

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-12
        • 2020-09-20
        • 1970-01-01
        • 2021-08-03
        相关资源
        最近更新 更多