angular - 使用复选框检查垫表中的最大项目
问题描述
我正在开发一个角度应用程序并使用带有 mat 复选框的 mat table。代码如下:
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!-- Checkbox Column -->
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox [(ngModel)]="row.checked" (change)="getCheckboxesData(row)">
</mat-checkbox>
</td>
</ng-container>
<!-- Position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="weight">
<th mat-header-cell *matHeaderCellDef> Weight </th>
<td mat-cell *matCellDef="let element"> {{element.weight}} </td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef> Symbol </th>
<td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selection.toggle(row)">
</tr>
</table>
import { SelectionModel } from '@angular/cdk/collections';
import { Component } from '@angular/core';
import { MatTableDataSource } from '@angular/material';
export interface PeriodicElement {
name: string;
position: number;
weight: number;
symbol: string;
}
const ELEMENT_DATA: PeriodicElement[] = [
{ position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' },
{ position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' },
{ position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' },
{ position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be' },
{ position: 5, name: 'Boron', weight: 10.811, symbol: 'B' },
{ position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C' },
{ position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N' },
{ position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O' },
{ position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F' },
{ position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne' }
];
/**
* @title Table with selection
*/
@Component({
selector: 'table-selection-example',
styleUrls: ['table-selection-example.css'],
templateUrl: 'table-selection-example.html'
})
export class TableSelectionExample {
public data: any;
displayedColumns: string[] = [
'select',
'position',
'name',
'weight',
'symbol'
];
dataSource = new MatTableDataSource<PeriodicElement>(ELEMENT_DATA);
selection = new SelectionModel<PeriodicElement>(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;
}
getCheckboxesData(row) {
if (row.checked === true) {
console.log(row);
this.data.push(row);
}
}
}
堆栈闪电战:
https://stackblitz.com/edit/angular-l4x28h?embed=1&file=app/table-selection-example.html
我想在复选框中实现一个功能,以便如果用户单击超过 3 个复选框(最多 3 个用户可以检查),这意味着当用户尝试检查第 4 个复选框时,我需要显示一个对话框并确保特定行数据不是添加到数组中。如果用户取消选中已选中的复选框,则应从数组中删除该特定项目。简而言之,我们应该允许随时检查最多 3 个项目。我怎样才能做到这一点?
解决方案
如果你改变你的getCheckboxData
功能如下:
getCheckboxesData(row) {
if (row.checked === true) {
if (!this.maxReached()) {
// 3 selected items not reached, so add this one
this.data.push(row);
} else {
// Needs to be done in a setTimeout - see https://github.com/angular/angular/issues/9275
setTimeout(() => {
// 3 selected items, so uncheck this one
row.checked = false;
// Display a dialog indicating there are too many items selected
this.dialog.open(WarningDialog);
});
}
} else if (row.checked === false) {
// Remove the row
this.data = this.data.filter(el => {
return el.symbol !== row.symbol;
});
}
console.log('selected', this.data);
}
这将执行检查maxReached()
以查看data
数组(包含所选项目)是否已包含 3 个项目。如果是这样,它将取消选中您刚刚检查的行(setTimeout
由于此问题在函数中执行此操作:https ://github.com/angular/angular/issues/9275 )并打开一个带有消息的对话框。
如果选择了 3 个项目,该maxReached()
函数仅返回 true,否则返回 false:
maxReached(): boolean {
return this.data.length === 3;
}
data
我在此处添加的另一段代码是如果您取消选中复选框,则会从数组中删除该项目。这使用filter
Array 的功能来定位正确的元素,然后将其从数组中删除。您需要向该类添加一个构造函数以TableSelectionExample
注入打开模式所需的服务:
constructor(public dialog: MatDialog) {}
该模型的代码如下:
打字稿
import { Component } from '@angular/core';
@Component({
selector: 'warning-dialog',
templateUrl: 'warning-dialog.html'
})
export class WarningDialog {}
HTML
<h2 mat-dialog-title>Too Many Selected</h2>
<mat-dialog-content class="mat-typography">
<p>You can only select a maximum of 3 elements</p>
</mat-dialog-content>
不要忘记在您的班级WarningDialog
中添加entryComponents
和。declarations
AppModule
这里有一个有效的 StackBlitz 。
推荐阅读
- java - Spring Boot AccessDecisionVoter 自定义未授权消息
- installation - 安卓手机上没有安装app
- c - OpenSSL 1.1 通过 IANA ID 获取密码套件
- components - 如何在苗条的故事书中使用“插槽”
- python - 通过浏览按钮选择目录
- django - 在django网站的views.py中从多对多字段中删除一个值
- python - Pytables:附加 Earray 的大小可以减小吗?
- reporting-services - 来自报告服务器的 SSRS 数据源网络相关错误,但 VS 有效
- vaticle-typedb - Grakn mem 问题 windows 本地安装
- azure - 消费计划 Azure 逻辑应用中的标准连接器如何收费