首页 > 解决方案 > Angular:如何删除选定的数据行?

问题描述

我正在使用<mat-radio-button>列表。当我首先单击然后单击第二个而不是单击第一个返回时。当我单击第一个单选按钮时,它不起作用。然后当我单击删除按钮时,它会先删除,然后再删除。

我提供了下面的代码和一个演示链接供您参考。

HTML

    <div class="example-container mat-elevation-z8">
  <mat-chip class="pointer" mat-raised-button color="primary" (click)="removeSelectedRows()">
    Remove Selected Rows
  </mat-chip>
  <mat-table #table [dataSource]="dataSource">

    <!-- Checkbox Column -->
    <ng-container matColumnDef="select">
      <mat-header-cell *matHeaderCellDef>
        <!-- <mat-checkbox (change)="$event ? masterToggle() : null"
                      [checked]="selection.hasValue() && isAllSelected()"
                      [indeterminate]="selection.hasValue() && !isAllSelected()">
        </mat-checkbox> -->
      </mat-header-cell>
      <mat-cell *matCellDef="let row">
        <mat-radio-button (click)="$event.stopPropagation()"
                      (change)="$event ? selection.toggle(row) : null"
                      [checked]="selection.isSelected(row)">
        </mat-radio-button>
      </mat-cell>
    </ng-container>

    <!-- Position Column -->
    <ng-container matColumnDef="position">
      <mat-header-cell *matHeaderCellDef> No. </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.position}} </mat-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container matColumnDef="name">
      <mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
    </ng-container>

    <!-- Weight Column -->
    <ng-container matColumnDef="weight">
      <mat-header-cell *matHeaderCellDef> Weight </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.weight}} </mat-cell>
    </ng-container>

    <!-- Symbol Column -->
    <ng-container matColumnDef="symbol">
      <mat-header-cell *matHeaderCellDef> Symbol </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.symbol}} </mat-cell>
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"
             (click)="selection.toggle(row)">
    </mat-row>
  </mat-table>

    <mat-paginator #paginator
                 [pageSize]="3"
                 [pageSizeOptions]="[5, 10, 20]"
                 >
  </mat-paginator>

</div>

零件

    displayedColumns = ['select', 'position', 'name', 'weight', 'symbol'];
  data = Object.assign( ELEMENT_DATA);
  dataSource = new MatTableDataSource<Element>(this.data);
  selection = new SelectionModel<Element>(true, []);


  @ViewChild(MatPaginator) paginator: MatPaginator;

  ngAfterViewInit() {
    this.dataSource.paginator = this.paginator;
  }

  constructor(){
    console.log(this.data);
  }

  /** Whether the number of selected elements matches the total number of rows. */
  isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
  }

  removeSelectedRows() {
    console.log(this.selection.selected)
     this.selection.selected.forEach(item => {
      let index: number = this.data.findIndex(d => d === item);
      console.log(this.data.findIndex(d => d === item));
      this.dataSource.data.splice(index,1);

      this.dataSource = new MatTableDataSource<Element>(this.dataSource.data);
    });
    this.selection = new SelectionModel<Element>(true, []);
    console.log(this.selection)
  }

  /** Selects all rows if they are not all selected; otherwise clear selection. */
  masterToggle() {
    this.isAllSelected() ?
      this.selection.clear() :
      this.dataSource.data.forEach(row => this.selection.select(row));
  }
}

谢谢并恭祝安康。

标签: angulartypescriptangular-materialradio-button

解决方案


您的问题是您尝试使用selection.selected它返回一个包含所有选择的行的数组,而实际上您只想从表中删除一个值。如果我们希望用户一次只能删除一行,我们只需要担心用户选择的最后一行。我们可以去掉$event.stopPropagation这样无论用户点击单选按钮还是点击行,都会触发相同的事件。

<mat-cell *matCellDef="let element; let i = index">
    <mat-radio-button [checked]="selectedIndex === i">
    </mat-radio-button>
</mat-cell>

...

<mat-row *matRowDef="let row; let i = index; columns: displayedColumns;" (click)="selectedIndex = i">
</mat-row>

然后在你的组件中

selectedIndex: number;

removeSelectedRows() {
    let index: number = this.selectedIndex;
    this.dataSource.data = [...this.dataSource.data.slice(0, index), ...this.dataSource.data.slice(index + 1)];
    this.selectedIndex = null; // This will not be required when position is used to delete element
}

我已经尝试不要在您的代码中更改太多并使用slice但 IMO 最好在Elementlike中使用唯一值position并使用filterdataSource.data.

<mat-cell *matCellDef="let element">
    <mat-radio-button [checked]="selectedPosition === element.position">
    </mat-radio-button>
</mat-cell>

...

<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selectedPosition = row.position">
</mat-row>

在组件中

selectedPosition: number;

removeSelectedRows() {
    this.dataSource.data = this.dataSource.data.filter(element => element.position !== this.selectedPosition);
}

这是StackBlitz上的一个工作示例。


推荐阅读