材质角度选择所有复选框

时间:2019-01-07 11:30:11

标签: angular checkbox angular-material

我正在尝试在棱角材质上实施选择所有复选框。当用户单击特定复选框(项目)时,主复选框应显示不确定,如果选中了所有复选框,则应变为选中。目前,我有一些奇怪的行为。谁能让我知道我在哪里犯错了?这是stackblitz。 这是我的示例代码:

app.html

<fieldset class="demo-fieldset">
  <div>
    <mat-checkbox aria-label="Select All" [checked]="isChecked(selected3, itemsObject)" [indeterminate]="isIndeterminate(selected3, itemsObject)" (click)="toggleAll(selected3, itemsObject)">
      Select All list of user (Array of objects) {{isChecked(selected3, itemsObject)}}
    </mat-checkbox>
  </div>
  <div class="demo-select-all-checkboxes" *ngFor="let item of itemsObject">
    <mat-checkbox [checked]="exists(item, selected3)" (click)="toggle(item, selected3)">
      {{ item.val }}
    </mat-checkbox>
    {{exists(item, selected3)}}

  </div>
</fieldset>

app.ts

import {
  Component
} from '@angular/core';

@Component({
  selector: 'app',
  templateUrl: 'app.html',
  styleUrls: ['app.css'],
})
export class CheckboxConfigurableExample {
  itemsObject = [{
    id: 1,
    val: 'john'
  }, {
    id: 2,
    val: 'jane'
  }];
  selected3 = [];

  toggle(item, list) {
    var idx = list.indexOf(item);
    if (idx > -1) {
      list.splice(idx, 1);
    } else {
      list.push(item);
    }
  }

  exists(item, list) {
    return list.indexOf(item) > -1;
  };

  isIndeterminate(x, t) {
    return (x.length !== 0 && x.length !== t.length);
  };

  isChecked(x, t) {
    return x.length === t.length;
  };

  toggleAll(x, t) {
    var l1 = x.length,
      l2 = t.length;
    if (l1 === l2) {
      x.splice(0, l1);
    } else if (l1 === 0 || l1 > 0) {
      //First we need to empty array, because we are using push to fill in array
      x.splice(0, l2);
      t.forEach(y => x.push(y));
    }
  };
}

这是我的stackblitz

4 个答案:

答案 0 :(得分:3)

Try this code:

**Component:**

        import {Component} from '@angular/core';
        import {

          MatCheckboxChange
        } from '@angular/material';

        /**
         * @title Configurable checkbox
         */
        @Component({
          selector: 'checkbox-configurable-example',
          templateUrl: 'checkbox-configurable-example.html',
          styleUrls: ['checkbox-configurable-example.css'],
        })
        export class CheckboxConfigurableExample {
          itemsObject = [{
            id: 1,
            val: 'john'
          }, {
            id: 2,
            val: 'jane'
          }];
          selected3 = [];

          toggle(item,event: MatCheckboxChange) {
             if (event.checked) {
              this.selected3.push(item);
            } else {
              const index = this.selected3.indexOf(item);
              if (index >= 0) {
                this.selected3.splice(index, 1);
              }
            }
           console.log(item + "<>", event.checked);
          }

          exists(item) {
            return this.selected3.indexOf(item) > -1;
          };

          isIndeterminate() {
            return (this.selected3.length > 0 && !this.isChecked());
          };

          isChecked() {
            return this.selected3.length === this.itemsObject.length;
          };



          toggleAll(event: MatCheckboxChange) { 

            if ( event.checked ) {

               this.itemsObject.forEach(row => {
                  // console.log('checked row', row);
                  this.selected3.push(row)
                  });

                // console.log('checked here');
            } else {
              // console.log('checked false');
               this.selected3.length = 0 ;
            }
        }
        }


**Template:**

       <fieldset class="demo-fieldset">
      <div>
         <mat-checkbox aria-label="Select All" [checked]="isChecked()" [indeterminate]="isIndeterminate()" (change)="$event ? toggleAll($event) : null">
          Select All list of user (Array of objects) {{isChecked(selected3)}}
        </mat-checkbox>
      </div>
      <div class="demo-select-all-checkboxes" *ngFor="let item of itemsObject">
        <mat-checkbox (click)="$event.stopPropagation()"
                        (change)="$event ? toggle(item, $event) : null"
                        [checked]="exists(item)">
          {{ item.val }}
        </mat-checkbox>
        {{exists(item)}}

      </div>
    </fieldset>

答案 1 :(得分:0)

在您的checkbox-configurable-example.html中,您使用:

[checked] = "isChecked(selected3, itemsObject)"

我只是将其更改为:

value="isChecked(selected3, itemsObject)"

看起来像您期望的那样? 我怀疑整个项目还需要进行一些调整,但这可能会让您朝正确的方向前进?

答案 2 :(得分:0)

另一种策略可能是绑定到对象和组件上的值,而不是调用方法。这样,您可能能够更有效地管理组件中的状态。

例如,您可以在对象模型中引入以下内容:

public itemsObject = [{
  id: 1,
  val: 'john',
  isChecked: false
}, {
  id: 2,
  val: 'jane',
  isChecked: false
}];

然后您可以使用以下方法将其绑定到复选框:

[checked]="item.isChecked"

绑定“ change”事件还将使您知道何时更改,然后您可以采取相应的行动:

<mat-checkbox [checked]="item.isChecked" (change)="itemChanged(item,$event)">

我创建了一个Stackblitz,其中显示了一个有效的示例:-

https://stackblitz.com/edit/angular-uuw7qh-ninwen

答案 3 :(得分:0)

在您的HTML上,添加如下内容:

<table class="table">
              <thead>
                <tr>
                  <th>
                    <mat-checkbox (change)="onChangeSelectAll($event)">Select/Deselect All</mat-checkbox>
                  </th>

                </tr>
              </thead>
              <tbody>
                <tr *ngFor="let item of offers">
                  <td>
                    <mat-checkbox [checked]="item.selected" (change)="selection($event, i, item)" name="chkInvoice"></mat-checkbox>
                  </td>                      
                </tr>
              </tbody>
            </table>

打开您的打字稿文件,

onChangeSelectAll(event) {
    if (event.checked) {
        this.offers.forEach(obj => {
            obj.selected = true;
        });
    }
    else {
        this.offers.forEach(obj => {
            obj.selected = false;
        });
    }
}