У меня есть список предметов вместе с соответствующими флажками.
И я хотел бы добиться следующего:
- выбрать / отменить выбор всех элементов в списке с помощью флажка «Выбрать все».
- выбрать / отменить-выбрать отдельные элементы в списке.
- , когда выбраны все элементы и выбран любой из выбранных элементов, снимите флажок «Выбрать все».
Большинство этих шагов работают должным образом, кроме случаев, когдаI:
- выбрать все элементы списка, установив флажок «Выбрать все»
- , отменить выбор любого из выбранных элементов
- , а затем снова проверить «Выбрать все»флажок.
Это приводит к тому, что любой элемент списка, который я не выбрал перед установкой флажка «Выбрать все», остается невыбранным.
Похоже, что (по какой-то причине) внутреннее состояние флажка в этом случае не изменяется.
Хотя, когда:
- все элементы списка не выбраны, и я выбираю любой из элементов списка
- , затем установите флажок «Выбрать все»
правильно выбирает все элементы списка.Так что я немного запутался, почему он не работает в другом случае, упомянутом выше.
Примечание. Основная причина, по которой я не хочу сохранять состояние для каждого элемента в списке, заключается в том, что я будуиспользовать это в таблице с виртуальной прокруткой.Который извлекает данные страницу за страницей. Таким образом, у меня нет доступа ко всем данным об элементах, поэтому я сохраняю только элементы, которые я выбрал вручную или не выбран.
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>
Старая кодовая ссылка
Решение