Angular 2复选框全选功能

7

问题

我在寻找解决这个问题的方法,但仍然卡住了。我有一个带有多行的表格,每一行都有一个复选框。我需要一个复选框来全选和取消全选,这是一些示例代码:

模板

<table class="table table-bordered table-condensed table-striped table-hover">
<thead>
    <tr>
        <th></th>
        <th>Size</th>
        <th>Diameter</th>
        <th class="text-center">
            <input type="checkbox" name="all" (change)="checkAll($event)"/>
        </th>
    </tr>
</thead>
<tbody>
    <tr *ngFor="let size of sizes | async ; let i = index">
        <td class="text-right">{{i + 1}}</td>
        <td class="text-right">{{size.size}}</td>
        <td>{{size.diameter}}</td>
        <td class="text-center">
            <input type="checkbox" name="sizecb[]" value="{{size.id}}"/>
        </td>
    </tr>
</tbody>

组件

    export class ListSizeComponent implements OnInit {
    constructor () {
    }

    sizes: any;

    setSizes() {
        this.sizes = [
            {'size': '0', 'diameter': '16000 km'},
            {'size': '1', 'diameter': '32000 km'}
        ]
    }

    checkAll(ev) {
        if (ev.target.checked) {
            console.log("True")
        } else {
            console.log("False");
        }
    }

    ngOnInit(): void {
        this.setSizes();
    }
}

请检查我的 Plunker 链接:http://plnkr.co/edit/K01n9vmSZyMi0VF5Nf1x?p=preview - Bharat Chauhan
8个回答

19

你可以利用ngModel来实现这个目标。

模板:

<input type="checkbox" name="all" [checked]="isAllChecked()" (change)="checkAll($event)"/>
....
<input type="checkbox" name="sizecb[]" value="{{size.id}}" [(ngModel)]="size.state"/>

组件:

checkAll(ev) {
  this.sizes.forEach(x => x.state = ev.target.checked)
}

isAllChecked() {
  return this.sizes.every(_ => _.state);
}

Stackblitz示例


我知道这个答案现在有点过时了,但是我正在尝试做同样的事情,但是我无法使其编译。它抱怨state不是size的属性。我错过了什么吗? - Plog
@Plog 你能在 Plunker 上重现它吗? - yurzui
我只是在做你的 Plunker 示例相同的代码,但它不知道“state”是什么。这是从哪里来的?? - Plog
@Plog 我明白了。试试 sizes: any[] 或者创建特殊类型。我也更新了 plunker。 - yurzui
非常感谢。很抱歉我对Angular非常陌生,进入其中有些困难。所以自你上次回答以来,Angular是否发生了一些变化? - Plog

11

这也可以在不使用[(ngModel)]的情况下完成!

只需在组件 'ListSizeComponent' 中声明并将布尔变量 'isSelected' 初始化为 false。 然后,将[Checked] =“isSelected”属性添加到所有复选框中。并将以下更改事件添加到“all”复选框中。 (change)="isSelected = true"。

因此,您的代码如下所示,

<table class="table table-bordered table-condensed table-striped table-hover">
<thead>
    <tr>
        <th></th>
        <th>Size</th>
        <th>Diameter</th>
        <th class="text-center">
            <input type="checkbox" name="all" (change)="isSelected = true"/>
        </th>
    </tr>
</thead>
<tbody>
    <tr *ngFor="let size of sizes | async ; let i = index">
        <td class="text-right">{{i + 1}}</td>
        <td class="text-right">{{size.size}}</td>
        <td>{{size.diameter}}</td>
        <td class="text-center">
            <input type="checkbox" name="sizecb[]" value="{{size.id}}" 
             [checked]="isSelected"/>
        </td>
    </tr>
</tbody>
</table>

组件:

export class ListSizeComponent implements OnInit {
constructor () {
}

sizes: any;
isSelected = false;

setSizes() {
    this.sizes = [
        {'size': '0', 'diameter': '16000 km'},
        {'size': '1', 'diameter': '32000 km'}
    ]
}



ngOnInit(): void {
    this.setSizes();
}

7
(change)="isSelected = !isSelected" 这将使复选框切换选中状态,即全选或取消全选。 - ArunDhaJ
切换的话,将(change) = "isSelected = !isSelected"用于切换选中状态。 - Amey P Naik
如果您需要默认选中复选框中的一个,但稍后又取消选中它,会发生什么? - DJG22

6
在HTML文件中:
选择所有复选框:
<div class="col-sm-6">
<input type="checkbox" (change)="isSelected = !isSelected"> Select all
</div>

选择复选框列表:

<div class="col-sm-6" *ngFor="let feature of features">
 <input type="checkbox" [checked]="isSelected"> {{feature.text}}
</div>

0

这里有一种更现代的方法,不需要使用ngModel或外部跟踪所选项目。纯MatSelectionList方法:

public toggle(list: MatSelectionList) {
    if (this.isAllChecked(list)) {
        list.deselectAll();
    } else {
        list.selectAll();
    }
}

public isAllChecked(list: MatSelectionList): boolean {
    // Make sure list exists
    if (!list.options)
        return false;
    return list.options.toArray().every(o => o.selected);
}

0
zone1 = [
    { name: 'Capot avant', checked: false },
    { name: 'Pare-chocs avant', checked: false }
  ]

get selectedZone1() {enter code here
    return this.zone1.filter(item => item.checked).map(item => item.name)
  }


        <!-- zone 1 -->
  <ul>
    <h3 class="titre font-weight-bold zone"><b>ZONE 1</b></h3>
    <li *ngFor="let item of zone1">
      <mat-checkbox [(ngModel)]="item.checked">
        {{item.name}}
      </mat-checkbox>
    </li>
  </ul>

谢谢您的回答。您能否提供一些关于这段代码样例所做的事情的信息呢? - Leogout

0

正确答案非常简单(基本上是重复Syed Muhammad Abid的答案)。

TS:

multiSelect: boolean = true;

HTML:

<table>
    <tr>
        <th><input type="checkbox" [checked]="multiSelect" (change)="multiSelect = !multiSelect"/></th>
        <th>Value</th>
   </tr>
   <tr *ngFor="let item of items">
       <td><input type="checkbox" [checked]="multiSelect" /></td>
       <td>{{item.value}}</td>
   </tr>
</table>

如果你在列表中选择了所有元素会发生什么?普通的复选框不会被选中。 - yurzui

0

实现全选复选框的示例代码。

<li> <input type="checkbox" [(ngModel)]="selectedAll" (change)="selectAll();"/>
          </li>
          <li *ngFor="let n of names"> 
          <input type="checkbox" [(ngModel)]="n.selected" (change)="checkIfAllSelected();">
          {{n.name}}
     </li>

.....

selectAll() {
    for (var i = 0; i < this.names.length; i++) {
      this.names[i].selected = this.selectedAll;
    }
  }
  checkIfAllSelected() {
    this.selectedAll = this.names.every(function(item:any) {
        return item.selected == true;
      })
  }

-1
它不起作用,我认为这是因为在我的实际代码中,我通过服务通过异步调用http.get获取“sizes”,并且我得到了这个错误:
this.sizes.every不是一个函数
我的意思是组件中的尺寸是一个可观察对象
我必须更正我的答案以澄清我的情况,我有一个服务,在该服务中以以下方式获取数组大小:
getSizes () {

    let sizesUrl = 'http://localhost:8000/sizes';

    return this.http.get(sizesUrl).map(this.extractData)
}

private extractData(res: Response) {
    let body = res.json();
    //console.log(body);
    let sizes: Size[] = new Array();
    for (let x = 0; x < body['hydra:member'].length; x++) {
        let size = new Size;
        let item = body['hydra:member'][x];
        size.id = item['@id'].substring(item['@id'].length - 1);
        size.size = item['size'];
        size.diameter = item['diameter'];
        size.example = item['example'];
        size.surfaceGravity = item['surfaceGravity'];
        sizes.push(size);
    }
    return sizes || { };
}

在组件中,sizes 是一个可观察对象,因此如果我调用 subscribe:
arr: any[];
sizes: any;

setSizes() {
    this.sizes = this.sizeService
        .getSizes()
        .subscribe(data => {
            this.arr = data;
        });
}

checkAll(ev) {
    if(!this.arr) return;
    this.arr.forEach(x => x.state = ev.target.checked)
}

isAllChecked() {
    if(!this.arr) return;
    return this.arr.every(_ => _.state);
}

ngOnInit(): void {
    this.setSizes();
}

我遇到了一个编译错误,"Type '{}' is not assignable to type any[]",并且 "sizes" 不再是 Observable 对象而是 Subscriber 对象,所以我无法在 async 管道中使用它。

对于所有的困惑和混淆,我很抱歉,我恐怕已经陷入了一个没有出路的隧道。

无论如何,还是感谢您的回答 :)


谢谢,问题是我代码中订阅的参数错误,该死的我没看到它,感谢你的帮助 :) - Lupo Wolfman Solitario

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接