我有一个项目列表及其关联的复选框。
我想实现以下目标:
除了我:
之外,这些步骤中的大多数都按预期工作这将导致在单击“全选”复选框之前未选择的所有列表项都保持未选中状态。
在这种情况下,似乎(由于某种原因)复选框的内部状态未更改。
虽然,当:
它正确选择了所有列表项。因此,我有点困惑为什么在上述其他情况下它不起作用。
注意:我不想存储列表中每个项目的状态的主要原因是,我将在带有虚拟滚动的表中使用它。哪个将逐页获取数据。.因此,我无法访问所有项目数据,因此,我只存储手动选择或未选择的项目。
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>
答案 0 :(得分:1)
代码真的很乱。我不会为布尔值而烦恼,可以对数组进行动态检查,并且复选框将正确更新状态。
这是更新的代码,您可以进行进一步的修改,但是您可以了解其工作原理。
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>