javascript - 复选框列表上的全选功能
问题描述
我有一个项目列表及其相关的复选框。
我想实现以下目标:
- 使用“全选”复选框选择/取消选择列表中的所有项目。
- 选择/取消选择列表中的单个项目。
- 当所有项目都被选中并单击任何选定项目时,取消选中“全选”复选框。
这些步骤中的大多数都按预期工作,除非我:
- 通过选中“全选”复选框来选择所有列表项
- 取消选中任何选定的项目
- 然后再次选中“全选”复选框。
这会导致我在单击“全选”复选框之前未选中的任何列表项保持未选中状态。
在这种情况下,看起来(由于某种原因)复选框的内部状态没有改变。
虽然,当:
- 所有列表项都未选中,我选择了任何列表项
- 然后选中“全选”复选框
它正确选择了所有列表项。所以我有点困惑,为什么它在上面提到的另一种情况下不起作用。
注意:主要原因,我不想为列表中的每个项目存储状态,是我将在带有虚拟滚动的表中使用它。它逐页获取数据。所以我无法访问所有项目数据,因此,我只存储我手动选择或未选择的项目。
app.component.ts
import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
constructor( private cdr: ChangeDetectorRef ) {
this.cdr.markForCheck();
}
public list = [
"item1", "item2", "item3", "item4", "item5"
];
public selected = {
ids: [],
all: false,
all_except_unselected: false
};
public toggleSelectItem( id: number, event: MouseEvent ): void {
if ( this.selected.all === true ) {
this.selected.all = false;
this.selected.all_except_unselected = true;
this.selected.ids = [];
}
if ( this.selected.all_except_unselected === true ){
this.selected.ids = [ ...this.selected.ids, id ];
} else if ( this.selected.all == false && this.selected.all_except_unselected == false ) {
if ( this.selected.ids.indexOf( id ) === -1 ) {
this.selected.ids = [ ...this.selected.ids, id ];
} else {
this.selected.ids = [ ...this.selected.ids].filter( itemId => itemId !== id );
}
}
console.log(this.selected.ids);
}
public isSelected( id: number ): boolean {
if ( this.selected.all === true ) {
console.log(id, 'selected all')
return true;
} else if ( this.selected.all_except_unselected === true ) {
console.log(id, 'selected all except unselected');
return true;
}
console.log(id, this.selected.ids.indexOf( id ) >= 0 ? 'selected' : 'unselected');
return this.selected.ids.indexOf( id ) >= 0;
}
public toggleSelectAll(): void {
if ( this.selected.all == false ) {
this.selected.ids = [];
}
this.selected.all = !this.selected.all;
this.selected.all_except_unselected = false;
console.log('selected all ', this.selected );
}
}
app.component.html
<input type="checkbox" [checked]="selected.all" (change)="toggleSelectAll()"> Select All
<br>
<br>
<div *ngFor="let item of list; let i = index" >
<input type="checkbox" [checked]="isSelected(i)" (change)="toggleSelectItem(i, $event)"> {{ item }}<br>
</div>
解决方案
代码真的很乱。我不会打扰布尔值,您可以即时检查数组,复选框将正确更新状态。
这是更新的代码,您可以进行进一步修改,但您可以了解它是如何工作的。
https://angular-hvbfai.stackblitz.io
import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
constructor(private cdr: ChangeDetectorRef) {
this.cdr.markForCheck();
}
public list = [
"item1", "item2", "item3", "item4", "item5"
];
public selected = {
ids: []
};
public allSelected() {
return this.selected.ids.length === this.list.length;
}
public toggleSelectItem(id: number, event: MouseEvent): void {
if (this.selected.ids.indexOf(id) === -1) {
this.selected.ids = [...this.selected.ids, id];
} else {
this.selected.ids = [...this.selected.ids].filter(itemId => itemId !== id);
}
console.log(this.selected.ids);
}
public isSelected(id: number): boolean {
return this.selected.ids.indexOf(id) >= 0;
}
public toggleSelectAll(): void {
if (this.allSelected()) {
this.selected.ids = [];
} else {
let i = 0;
this.list.forEach(element => {
if (this.selected.ids.indexOf(i) === -1) {
this.selected.ids = [...this.selected.ids, i];
}
i++;
});
}
console.log('selected all ', this.selected);
}
}
HTML:
<input type="checkbox" [checked]="allSelected()" (change)="toggleSelectAll()"> Select All
<br>
<br>
<div *ngFor="let item of list; let i = index" >
<input type="checkbox" [checked]="isSelected(i)" (change)="toggleSelectItem(i, $event)"> {{ item }}<br>
</div>
推荐阅读
- amazon-web-services - 当我不通过 SSL/TLS 连接时,为什么 Amazon RDS 会显示证书颁发机构?
- angularjs - 在 Angular JS 中,有没有办法在不使用 scope.watch 的情况下监视 DOM 的变化?
- python - 更改 HTML 文本并保存回 HTML
- python-2.7 - 正斜杠在本地环境中被忽略,但在全局环境中不被忽略
- mysql - MySQL 服务器的高 CPU 使用率
- numpy - PyTorch - 到 NumPy 产生未调整大小的对象?
- python - 我可以在 WordNet 中保存引理的原始共轭吗?
- sql - Oracle SQL 过滤两个日期之间的结果,但只显示一个时间范围内的记录
- r - 是否可以使用 ggplot2 从数据框之外的这些数据制作箱线图?
- python - __new__ 方法给出错误 object.__new__() 只接受一个参数(要实例化的类型)