我正在建立一个带有分页的表,该表根据一组选定的复选框来处理一些动作;我有docs,到目前为止,只选择了几行中的所有行,一切都很好;
我要开始工作的场景如下:如果我在PageSize
上的paginator
是“ 10”,并且我单击masterToggle
以选择“全部”行,我希望选择当前页面上的所有行,仅此而已,这就是当前PageSize
所显示的10行,但是,这会选择整个dataSource
表中大约有300条记录。
是否有一种方法可以使masterToggle
仅选择基于PageSize显示的行?然后,如果我将PageSize
更改为20,则只有前10个保持选中状态。
这是我的代码。
/** 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));
}
答案 0 :(得分:5)
如果您使用排序,分页和过滤:
HTML列:
<mat-checkbox (change)="$event ? masterToggle($event) : null"
[checked]="selection.hasValue() && isEntirePageSelected()"
[indeterminate]="selection.hasValue() && !isEntirePageSelected()"
[aria-label]="checkboxLabel()"></mat-checkbox>
组件:
getPageData() {
return this.dataSource._pageData(this.dataSource._orderData(this.dataSource.filteredData));
}
isEntirePageSelected() {
return this.getPageData().every((row) => this.selection.isSelected(row));
}
masterToggle(checkboxChange: MatCheckboxChange) {
this.isEntirePageSelected() ?
this.selection.deselect(...this.getPageData()) :
this.selection.select(...this.getPageData());
}
checkboxLabel(row): string {
if (!row) {
return `${this.isEntirePageSelected() ? 'select' : 'deselect'} all`;
}
return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.id + 1}`;
}
答案 1 :(得分:1)
通过删除masterToggle()
方法的最后一行,并用循环遍历分页器PageSize并调用select
方法的自定义函数来替换它,可以使其工作SelectionModel
为其发现的每个警报;我还更改了isAllSelected
方法,以比较PageSize
和选定的lenght
而不是整个dataSource
。
/** Whether the number of selected elements matches the total number of rows. */
isAllSelected() {
const numSelected = this.selection.selected.length;
const page = this.dataSource.paginator.pageSize;
return numSelected === page;
}
/** Selects all rows if they are not all selected; otherwise clear selection. */
masterToggle() {
this.isAllSelected() ?
this.selection.clear() : this.selectRows();
}
selectRows() {
for (let index = 0; index < this.dataSource.paginator.pageSize; index++) {
this.selection.select(this.dataSource.data[index]);
this.selectionAmount = this.selection.selected.length;
}
}
答案 2 :(得分:1)
我的解决方案基于当前显示的行,因此可以在分页方面使用。 有很多需要改进的地方,请随时进行改进。
isAllSelected() {
const numSelected = this.selection.selected.length;
const displayedRows = this.filteredEvents.connect().value.length;
let isAllSelected = (numSelected === displayedRows);
if (isAllSelected) {
isAllSelected = this.isAllDisplayedSelected();
}
return isAllSelected;
}
isAllDisplayedSelected() {
let isAllDisplayedSelected = true;
if (this.selection.selected.length === 0) {
return this.isAllSelected();
}
this.filteredEvents.connect().value.some(element => {
if (!this.selection.isSelected(element)) {
isAllDisplayedSelected = false;
return isAllDisplayedSelected;
}
});
return isAllDisplayedSelected;
}
masterToggle() {
this.isViewableSelected() ?
this.deselectRows() :
this.selectRows();
}
isViewableSelected() {
return (this.isAllSelected() || this.isAllDisplayedSelected());
}
deselectRows() {
const itemsToBeUnselected = this.filteredEvents.connect().value;
itemsToBeUnselected.forEach(element => {
this.selection.deselect(element);
});
}
selectRows() {
const currentlyDisplayedRows = this.filteredEvents.connect().value;
for (let index = 0; index < currentlyDisplayedRows.length; index++) {
this.selection.select(currentlyDisplayedRows[index]);
this.selectionAmount = this.selection.selected.length;
}
}
HTML:
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null" [checked]="selection.hasValue() && isViewableSelected()"
[indeterminate]="selection.hasValue() && !isViewableSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)">
</mat-checkbox>
</td>
</ng-container>
答案 3 :(得分:1)
这是我的解决方案。 https://angular-vkz1dp.stackblitz.io 我内置了一个额外的if开关页面,它将取消选中。
HTML列:
<mat-checkbox #ref
(click)="$event.stopPropagation()"
(change)="$event ? masterToggle(ref) : null"></mat-checkbox>
HTML单元格:
<mat-checkbox (click)="$event.stopPropagation()"
[checked]="selection.isSelected(element)"></mat-checkbox>
HTML分页器:
<mat-paginator fixed [pageSizeOptions]="[20, 50, 100]" [pageSize]="20" (page)="pageChange()" showFirstLastButtons></mat-paginator>
组件:
@ViewChild('ref') ref: any;
masterToggle(_ref: any) {
if(_ref.checked){
this.checkPageOnly();
}
else {
this.selection.clear();
}
}
checkPageOnly() {
let i = this.dataSource.paginator.pageIndex * this.dataSource.paginator.pageSize;
let end = (this.dataSource.paginator.pageIndex + 1) * this.dataSource.paginator.pageSize;
for(i; i < end; i++) {
this.selection.select(this.dataSource.data[i]);
}
}
pageChange() {
this.ref.checked = false;
this.masterToggle(this.ref);
}
}
答案 4 :(得分:0)
isAllSelected() {
// const numSelected = this.selection.selected.length;
// const numRows = this.dataSource.data.length;
// return numSelected === numRows;
// const page = this.dataSource.paginator.pageSize;
// return numSelected === page;
return this.selection.selected.length > 0;
}
/** 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));
this.selectRows();
}
pageChanged(event) {
this.selection.clear();
}
selectRows() {
const intIndex = this.dataSource.paginator.pageIndex === 0 ? 0 : (this.dataSource.paginator.pageSize * this.dataSource.paginator.pageIndex);
let intPageSize = intIndex + this.dataSource.paginator.pageSize;
if (intPageSize > this.dataSource.filteredData.length) {
intPageSize = this.dataSource.filteredData.length;
}
for (let index = intIndex; index < intPageSize; index++) {
this.selection.select(this.dataSource.filteredData[index]);
// this.selectionAmount = this.selection.selected.length;
}
}
/** The label for the checkbox on the passed row */
checkboxLabel(row?: TicketMatchingElement): string {
if (!row) {
return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
}
return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.bookingId + 1}`;
}
formatDateValue(dateValue: Date) {
return formatDate(dateValue);
}
}
HTML仅在分页中更改
<mat-paginator [pageSizeOptions]="[5, 10, 20,25]"
showFirstLastButtons (page)="pageChanged($event)"
></mat-paginator>
答案 5 :(得分:0)
刚刚找到this answer
您可以使用 datasource.connect().value
获取当前在您的表格中呈现的所有项目。
因此,根据您的代码,您可以:
masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.connect().value.forEach(row => this.selection.select(row));
}
答案 6 :(得分:0)
我找到了一种更简单的方法(Angular):
而不是 this.dataSource.data.length
将其更改为 this.dataSource.connect().value.forEach(row => this.selection.select(row));
类似的东西:
masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.connect().value.forEach(row => this.selection.select(row));
}
但这里唯一的问题是,它不会清除所有选定的字段;所以要实现这一点,请更改您的 isAllSelected() 方法:
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.paginator != undefined ? this.dataSource.paginator.pageSize : 5;
return numSelected === numRows;
}
这里的“5”是您的原始页面大小,在您的数据源未初始化之前定义。