我正在尝试使用角度和打字稿在经过排序的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点击选择以处理排序后的数据,而不是未排序后的数据?
答案 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<
// models.js
export const foo = writable();
export const bar = writable();
export const baz = writable();
<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>