【问题标题】:Removing selected rows from the table in angular 2 using angular material table使用角度材料表从角度2中的表中删除选定的行
【发布时间】:2018-01-20 08:33:52
【问题描述】:

我正在尝试使用角度材料选择表在角度 2 中实现一个简单的表。

我使用一个按钮从表中删除选定的行。但是单击该按钮我如何删除这些行?

下面显示的是我的表格 html 文件

<div class="example-container mat-elevation-z8">
  <mat-table #table [dataSource]="dataSource">

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

    <!-- Number Column -->
    <ng-container matColumnDef="num">
      <mat-header-cell style="max-width: 100px;" *matHeaderCellDef> No. </mat-header-cell>
      <mat-cell style="max-width: 100px;" *matCellDef="let element"> {{element.num}} </mat-cell>
    </ng-container>

    <!-- Message Column -->
    <ng-container matColumnDef="name">
      <mat-header-cell *matHeaderCellDef> Message </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.name}} </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]="10"
                 [pageSizeOptions]="[5, 10, 20]">
  </mat-paginator>
</div>

<br/>
<button style="background: #3B4990; color:white;" (click)="deleted($event)">Remove Selected Messages</button>

下面显示的是我的 .ts 文件。

import {Component, ViewChild} from '@angular/core';
import {MatPaginator, MatTableDataSource} from '@angular/material';
import {SelectionModel} from '@angular/cdk/collections';


@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
   styleUrls: ['./home.component.scss']
})


export class HomeComponent {

displayedColumns = ['select', 'num', 'name'];
  dataSource = new MatTableDataSource<Element>(ELEMENT_DATA);



  @ViewChild(MatPaginator) paginator: MatPaginator;

  /**
   * Set the paginator after the view init since this component will
   * be able to query its view for the initialized paginator.
   */
  ngAfterViewInit() {
    this.dataSource.paginator = this.paginator;
  }

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

  /** 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;
  }

  /** 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));
  }

    deleted($event)
{ 
 delete(this.dataSource.data.forEach(row => this.selection.select(row));)
}

}

export interface Element {
  name: string;
  num: number;
}

const ELEMENT_DATA: Element[] = [
  {num: 1, name: 'Message1'},
  {num: 2, name: 'Message2'},
  {num: 3, name: 'Message3'},
  {num: 3, name: 'Message4'},
  {num: 4, name: 'Message5'},
  {num: 5, name: 'Message6'},
];

任何人都可以帮助我如何使用按钮从表格中删除选定的行。

【问题讨论】:

    标签: angular angular-material2


    【解决方案1】:

    您应该删除选定的项目并刷新datasource,如下所示,

    removeSelectedRows() {
        this.selection.selected.forEach(item => {
           let index: number = this.data.findIndex(d => d === item);
           console.log(this.data.findIndex(d => d === item));
           this.data.splice(index,1)
           this.dataSource = new MatTableDataSource<Element>(this.data);
         });
         this.selection = new SelectionModel<Element>(true, []);
      }
    

    LIVE DEMO

    【讨论】:

    • 根据选择只删除一部分是不是不能全部删除?
    • @Aravind 感谢 LiveDemo,尽管当我点击删除按钮时查看时,我仍然可以看到它没有被删除的行。正常吗?我正在使用谷歌浏览器
    • 在你的例子中,如果之前的数据源有一些分页器和排序,你不会失去它们吗?像@ViewChild('myPaginator') myPaginator: MatPaginator;在 onInit() -> dataSource.paginator = myPaginator;
    • @Sithys 示例现在可以正常工作了!感谢您的通知
    • 伟大的工作兄弟。它对我有用,只需稍加修改,我也可以添加部分。@Aravind
    【解决方案2】:

    您可以使用MatTable API 中的renderRows() 方法。

    这样您不必在每次点击时都重新实例化数组。

    Check-out the Live Demo

    【讨论】:

    • 只有 Angular 6 方法吗?
    • 是的也看到了,但不知何故我找不到这个方法 inn MatTable using Angular 5 :(
    • @LoganWlv 介绍于V.5.2.x
    • 您的现场演示链接很有帮助,但我无需致电 renderRows() 即可使用
    【解决方案3】:

    你可以试试下面吗?

      removeSelectedRows() {
        var oldData = this.dataSource.data;
        var oldData = oldData.filter((item) => !this.selection.selected.includes(item));
        this.dataSource = new MatTableDataSource<Topic>(oldData);
        this.selection.clear()
        this.dataSource.filter = "";
      }
    

    【讨论】:

    • 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
    【解决方案4】:

    感谢 Aravind,他的回答帮助我解决了同样的问题。但是,我不喜欢 MatTableDataSouce 在 forEach 循环中,因为我认为这意味着它在每个循环上创建一个新的数据源。另外,对我来说,创建一个新的 MatTableDataSource 会破坏我对默认分页器的使用。所以我修改了他的答案,并在这里为任何可能受益的人发帖。

    removeSelectedRows() {   
        //sort the selected rows first so that they are in descending order
        //this allows us to splice without the index getting confused
        let selectedRows = this.selection.selected.sort((a,b) => {return b.position - a.position});
    
        let ds = this.dataSource.data; //take a copy
    
        selectedRows.forEach(item => {
            ds.splice(item.position-1,1); //splice out the selected rows
        });
        this.dataSource.data = ds;  //set the datasource so it fires the refresh
    
        this.selection = new SelectionModel<Element>(true, []);
    }
    

    尚未对其进行测试,但我的猜测是接受的答案和我的答案都需要进行一些清理,因为位置将不同步,这可能意味着后续调用失败。

    【讨论】:

    • 后续调用确实失败了...需要在设置数据源之前添加几行 let i = 1; ds.forEach(item => { item.position = i++; });
    猜你喜欢
    • 1970-01-01
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 2018-10-01
    相关资源
    最近更新 更多