角垫表和Shift单击选择

时间:2018-08-20 08:56:45

标签: angular typescript

我正在尝试使用角度和打字稿在经过排序的MatDataTable上实现Shift Click功能。

基本的缺点是,每当在表上注册一个click事件时,都会存储所选的行。

如果检测到Shift单击,则组件将尝试在最后选择的行和当前选择的行之间进行选择(就像在Windows中使用Shift Click选择一样)。

我拥有的事件处理代码如下:

clickHandler(event, row, index) {
    console.log('index clicked: ' + index);
    if (event.ctrlKey) {
        this.selectRows(row, index); // This records this.lastSelected
    } else if (event.shiftKey) {
        this.selectRowsFill(row, index); 
    } else {
        this.selectElement(row, index); // As does this call.
    }
}

// This function computes a start and end point for autoselection of 
// rows between this.lastSelected, and the currently clicked row
selectRowsFill(row, index) {
    const indexA = this.lastSelected;
    const indexB = index;
    if (indexA > indexB) {
        // Descending order
        this.selectRowsBetween(indexB, indexA);
    } else {
        // Ascending order
        this.selectRowsBetween(indexA, indexB);
    }
}

// And this performs the actual selection.
private selectRowsBetween(start, end) {
    let currentIndex = 0;
    this.dataSource.data.forEach(row => {
        if (currentIndex >= start && currentIndex <= end) {
            this.selection.select(row);
        }
        currentIndex++;
    });
}

和HTML:

<mat-row *matRowDef="let row; let i = index; columns: cols;" (click)="clickHandler($event, row, i)" [ngClass]="{'inDatabase' : isAdded(row), 'highlight': isSelectedAndAdded(row) || isSelected(row) }">

只要表未排序,此代码即可正常工作。一旦对MatTableDataSource应用排序算法,它就会更改数据顺序,从而导致选择失败。看起来选择是根据MatTableDataSource中数据的原始(未排序)顺序进行的。

那么我如何获得Shift点击选择以处理排序后的数据,而不是未排序后的数据?

4 个答案:

答案 0 :(得分:1)

将此行添加到 mat-checkbox

(click)="$event.stopPropagation(); ShiftKeyDown($event, i + (paginator.pageIndex * paginator.pageSize));"

<ng-container matColumnDef="Select" class="mr-2 mt-2">
  <th mat-header-cell *matHeaderCellDef [hidden]="model.StepCode != 'not_started'">
    <mat-checkbox (change)="$event ? masterToggle() : null; checked()"
      [checked]="selection.hasValue() && isAllSelected()"
      [indeterminate]="selection.hasValue() && !isAllSelected()" [aria-label]="checkboxLabel()">
    </mat-checkbox>
  </th>
  <td mat-cell *matCellDef="let row; let i = index" [hidden]="model.StepCode != 'not_started'">
    <mat-checkbox
      (click)="$event.stopPropagation(); ShiftKeyDown($event, i + (paginator.pageIndex * paginator.pageSize));"
      (change)="
        $event ? selection.toggle(row) : null; checked()" [checked]="selection.isSelected(row)"
      [aria-label]="checkboxLabel(row)">
    </mat-checkbox>
  </td>
</ng-container>

在打字稿中创建这个方法

 lastSelectedSegmentRow = 1; // this is the variable which holds the last selected row index
 ShiftKeyDown(event, lastRow) {
    if (event.shiftKey) {
      let obj: SegmentFile[] = Object.assign([], this.dataSource.data).filter((val, i) => {
        return i > this.lastSelectedSegmentRow && i < lastRow
      });
      
      obj.forEach(e => this.selection.select(e))
    }
    this.lastSelectedSegmentRow = lastRow;
  }

答案 1 :(得分:0)

事实证明,我只需要连接到数据源,并存储作为表中呈现行的元素数组:

ngOnChanges(changes: SimpleChanges) {
    this.dataSource.sort = this.sort;
    this.dataSource.connect().subscribe(d => this.renderedData = d);
}

然后我可以遍历该集合:

// And this performs the actual selection.
private selectRowsBetween(start, end) {
    let currentIndex = 0;
    this.renderedData.forEach(row => {
        if (currentIndex >= start && currentIndex <= end) {
            this.selection.select(row);
        }
        currentIndex++;
    });
}

答案 2 :(得分:0)

这是我的解决方案:>STACKBLITZ<

脱机情况下代码保存处于脱机状态

  • html
// models.js
export const foo = writable();
export const bar = writable();
export const baz = writable();
  • ts(指令)
<table [shiftClickSource]="dataSource"
       [shiftClickSelectModel]="selection"
       [shiftClickSourceId]="['position']"
       mat-table [dataSource]="dataSource" class="mat-elevation-z8" matSort>

....

答案 3 :(得分:0)

将此内容放入.html文件:-

1[T] timeOut) [0x0013d] in <a0c3f09cbf9049cbb8d3a680a53dcf46>:0   at Xamarin.UITest.Shared.Http.HttpClient.Post (System.String endpoint, System.String arguments, Xamarin.UITest.Shared.Http.ExceptionPolicy exceptionPolicy, System.Nullable

将其放入.ts文件:-

<mat-checkbox (click)="$event.stopPropagation()" (keyup)="checkboxTest(row, $event.key)" (change)="$event ? selection.toggle(row) : null" [checked]="selection.isSelected(row) "color="primary" [aria-label]="checkboxLabel(row)"></mat-checkbox>