функция выбора всех в списке флажков - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть список предметов вместе с соответствующими флажками.

И я хотел бы добиться следующего:

  • выбрать / отменить выбор всех элементов в списке с помощью флажка «Выбрать все».
  • выбрать / отменить-выбрать отдельные элементы в списке.
  • , когда выбраны все элементы и выбран любой из выбранных элементов, снимите флажок «Выбрать все».

Большинство этих шагов работают должным образом, кроме случаев, когдаI:

  • выбрать все элементы списка, установив флажок «Выбрать все»
  • , отменить выбор любого из выбранных элементов
  • , а затем снова проверить «Выбрать все»флажок.

Это приводит к тому, что любой элемент списка, который я не выбрал перед установкой флажка «Выбрать все», остается невыбранным.

enter image description here

Похоже, что (по какой-то причине) внутреннее состояние флажка в этом случае не изменяется.

Хотя, когда:

  • все элементы списка не выбраны, и я выбираю любой из элементов списка
  • , затем установите флажок «Выбрать все»

правильно выбирает все элементы списка.Так что я немного запутался, почему он не работает в другом случае, упомянутом выше.

Примечание. Основная причина, по которой я не хочу сохранять состояние для каждого элемента в списке, заключается в том, что я будуиспользовать это в таблице с виртуальной прокруткой.Который извлекает данные страницу за страницей. Таким образом, у меня нет доступа ко всем данным об элементах, поэтому я сохраняю только элементы, которые я выбрал вручную или не выбран.

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>

Старая кодовая ссылка

Решение

1 Ответ

0 голосов
/ 07 февраля 2019

Код действительно грязный.Я не стал бы беспокоиться о логических значениях, вы можете проверять массив на лету, и флажки будут корректно обновлять состояние.

Вот обновленный код. Вы можете внести дополнительные изменения, но вы можете получить представление о том, как это работает.

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>
...