自存使用angular selectionModel实现表格跨页勾选

根本是使用selectionModel,它本身储存的选中项就是一个能够不随切换分页而变化。这样太好了,

而表格的dataSource是会随分页变的,此前储存的选中项就匹配不上切换分页再切换回来的项。

要做的只是:

1.监听多选框选中的变化 ,储存它,并在切换分页后,把已经存好的拿出来。

2.再细节优化就是html上是否全选本页,通过在储存的选中项目加上pageIndex本页属性,就可以通过属性判断是否本页的来设置未决定状态

  1. component.ts
    import { SelectionModel } from "@angular/cdk/collections";
    import { MatTableDataSource } from "@angular/material/table";
    import { Component, OnInit } from "@angular/core";
    
    export class SingleCommodityManageComponent  implements OnInit {
      dataSource = new MatTableDataSource<any>([]);//表格
      selection = new SelectionModel<any>(true, []);
      selectedIds: any[] = []; // 存储选中项 ID 的数组
    
    
      ngOnInit(): void {
        this.queryCommidityInfo();
        this.selection.changed.subscribe((changes) => {
          const { added, removed } = changes;
    
          if (removed.length > 0) {
            // 创建一个 Set 来存储 removed 项的 comUUID
            const removedComUUIDs = new Set(removed.map((item) => item.comUUID));
    
            // 直接使用 filter 方法移除匹配的项,并创建一个新数组
            this.selectedIds = this.selectedIds.filter(
              (item) => !removedComUUIDs.has(item.comUUID)
            );
          }
    
          if (added.length > 0) {
            const addedItems = added.map((item) => ({
              comUUID: item.comUUID,
              pageIndex: this.options.pageIndex,
            }));
            this.selectedIds = this.selectedIds.concat(addedItems);
          }
        });
      }
    
    
      // 分页器变化
      paginatorChange(val) {
       // this.options.pageIndex = val.pageIndex;
        //this.options.numPerPage = val.pageSize;
        this.queryCommidityInfo();
      }
    
      // 分页查询商品信息
      queryCommidityInfo() {
     //...调接口
              this.reshowCheckedItems();//复显已勾选
     
      }
    
    
    
    // 多选函数
    
      /* 重新在页面显示之前已经添加到选中的项 */
      reshowCheckedItems() {
        this.dataSource.data.forEach((row) => {
          if (
            this.selectedIds.some(
              (selectedItem) => selectedItem.comUUID === row.comUUID//如果数据为被选中的
            )
          ) {
            const oldItem = this.selection.selected.find(//找到selected旧数据的项
              (item) => item.comUUID == row.comUUID
            );
            if (oldItem) {
              this.selection.deselect(oldItem); // 给原来的selected旧数据设置为不选中
            }
            this.selection.select(row); // 给新的dataSource设置为选中
          }
        });
      }
    
      /* 本页是否全选 */
      isThisPageAllSelected() {
        const numRows = this.dataSource.data.length;
        const thisPageSelected = this.selectedIds.filter(
          (item) => item.pageIndex == this.options.pageIndex
        ).length;
        return thisPageSelected === numRows;
      }
    
      /*  本页是否部分选择中 */
      isThisPageSomeSelected() {
        const isSomeSelected = this.selectedIds.some(
          //some() 方法测试数组中是否至少有一个元素通过了由提供的函数实现的测试。如果在数组中找到一个元素使得提供的函数返回 true,则返回 true;否则返回 false
          (item) => item.pageIndex == this.options.pageIndex
        );
        return isSomeSelected;
      }
    
      /*本页全选*/
      masterToggle() {
        if (this.isThisPageAllSelected()) {
          const thisPageSelectedIds = new Set(
            this.selectedIds
              .filter((item) => item.pageIndex === this.options.pageIndex)
              .map((item) => item.comUUID) //集合(Set) 是一种用于存储一组不同元素的数据结构
          ); //获取当前页码
    
          this.selection.selected.forEach((selectedItem) => {
            if (thisPageSelectedIds.has(selectedItem.comUUID)) {
              this.selection.deselect(selectedItem); //取消选中
            }
          });
          return;
        }
    
        this.selection.select(...this.dataSource.data);
      }
    }

 2.html

          <table mat-table [dataSource]="dataSource" class="mat-elevation-z0">
            <ng-container matColumnDef="select">
              <th mat-header-cell *matHeaderCellDef>
                <mat-checkbox
                  color="primary"
                  (click)="$event.stopPropagation()"
                  (change)="$event ? masterToggle() : null"
                  [checked]="selection.hasValue() && isThisPageAllSelected()"
                  [indeterminate]="
                    isThisPageSomeSelected() && !isThisPageAllSelected()
                  "
                >
                </mat-checkbox>
              </th>
              <td mat-cell *matCellDef="let row">
                <mat-checkbox
                  color="primary"
                  (click)="$event.stopPropagation()"
                  (change)="$event ? selection.toggle(row) : null"
                  [checked]="selection.isSelected(row)"
                >
                </mat-checkbox>
              </td>
            </ng-container>


            <tr mat-header-row *matHeaderRowDef="tableColumnArr"></tr>
            <tr
              mat-row
              *matRowDef="let row; columns: tableColumnArr"
              (click)="selection.toggle(row)"
            ></tr>
          </table>
          <div class="d-flex flex-row align-items-center">
            <div>
              已选中:{{ this.selectedIds.length }}
              <span class="ml-3"> 全部:{{ this.options.totalCount }}</span>
            </div>

            <div class="spacer"></div>
            <mat-paginator
              showFirstLastButtons
              [pageSizeOptions]="pageSizeOptions"
              [length]="options.totalCount"
              [pageIndex]="options.pageIndex"
              [pageSize]="options.numPerPage"
              (page)="paginatorChange($event)"
            ></mat-paginator>

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以,以下是一个简单的使用 Angular 实现分页功能的例子: 首先,安装 ngx-pagination 库,这是一个方便的 Angular 分页插件。 ``` npm install ngx-pagination --save ``` 接下来,在需要分页的组件中导入 ngx-pagination: ```typescript import { NgModule } from '@angular/core'; import { NgxPaginationModule } from 'ngx-pagination'; @NgModule({ imports: [ NgxPaginationModule ] }) ``` 在组件类中定义一个数组来存储所有要展示的数据: ```typescript export class MyComponent { data = [ { id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 3, name: 'Bob' }, { id: 4, name: 'Alice' }, { id: 5, name: 'Jim' }, { id: 6, name: 'Mary' }, { id: 7, name: 'Tom' }, { id: 8, name: 'Lucy' }, { id: 9, name: 'David' } ]; } ``` 在组件模板中,使用 ngx-pagination 指令来实现分页: ```html <table> <thead> <tr> <th>ID</th> <th>Name</th> </tr> </thead> <tbody> <tr *ngFor="let item of data | paginate: { itemsPerPage: 3, currentPage: p }"> <td>{{item.id}}</td> <td>{{item.name}}</td> </tr> </tbody> </table> <pagination-controls (pageChange)="p = $event"></pagination-controls> ``` 在上述模板中,我们使用了 *ngFor 指令来循环渲染每一页的数据,同时使用了 paginate 指令来进行分页。其中,itemsPerPage 表示每页显示几条数据,currentPage 表示当前页码。而 pagination-controls 是 ngx-pagination 提供的组件,用来实现分页控件。 好了,这样就实现了一个简单的 Angular 分页功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值