Angular 2全选/取消全选复选框

3
我想要选择/取消所有复选框。我尝试参考其他代码,但对我没有用。
以下是我的代码。选择取消特定单元对我有用。基本上,当我点击div时,它会选择/取消选择复选框并添加颜色。但我对全选/取消全选感到困惑。
请帮助我使用我的代码完成它。

//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { ReactiveFormsModule, FormGroup, FormBuilder } from '@angular/forms';

@Component({
  selector: 'my-app',
  template: `
  <form [formGroup]="form">
    <div formArrayName="unitArr">
    <label><input type="checkbox" />Select all</label>
    <label><input type="checkbox" />unSelect all</label>
      <div 
        *ngFor="let unit of units; let i = index"
        class="unit"
        (click)="onClick(i)"
        [ngClass]="{'unit-selected': unitArr.controls[i].value}">
          <input type="checkbox" formControlName="{{i}}"/>
          <div class="unit-number">{{ unit.num }}</div>
          <div class="unit-desc">{{ unit.desc }}</div>
      </div>
    </div>
  </form>
  `,
  styles: [`.unit-selected { color: red; }`]
})
export class App implements OnInit{
  private units = [
    {num: 1, desc: 'Decription'},
    {num: 2, desc: 'Decription'},
    {num: 3, desc: 'Decription'},
  ];
  private form: Form;
  
  constructor (private fb: FormBuilder) {}
  
  ngOnInit () {
    this.form = this.fb.group({
      unitArr: this.fb.array(
        this.units.map((unit) => {
          return this.fb.control(false); // Set all initial values to false
        })
      )
    });
  }
  
  // Shorten for the template
  get unitArr (): FormArray {
    return this.form.get('unitArr') as FormArray;
  }

  onClick(i) {
    const control = this.unitArr.controls[i];
    control.setValue(!control.value); // Toggle checked
  }
}

@NgModule({
  imports: [ BrowserModule, ReactiveFormsModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}


我猜你正在寻找类似于这个的东西。 - Rahul Singh
为什么不将此作为答案发布,而不是评论呢? - Graham
不要写成这样:formControlName="{{i}}",而应该写成这样:[formControlName]="i" - Nate
回答你的问题,你可以简单地将所有值(https://angular.io/api/forms/AbstractControl#patchValue)修补为false/true。 - Nate
为什么人们在评论中提供答案? - Graham
1个回答

3
通过结合Rahul和ncohen所提供的评论,我们可以在此处使用patchValue。
至于取消所有复选框的选择,我在此答案中将其更改为按钮,因为我认为复选框不太适合(?)处理复选框中的勾选。但是如果你更愿意使用复选框,则由你决定。
至于检查“全选”复选框是否应该被选中,您可以执行以下操作:
[checked]="checkAllSelected()"

然后在TS中:

checkAllSelected() {
  return this.form.controls.unitArr.controls.every(x => x.value == true)
}

在这里,我们必须记住每次变更检测都会运行此操作。因此,也许您想使用一个变量来代替,当然这取决于具体情况,即对您而言成本是否高昂,但我认为在这种情况下不会。

因此,您的模板可能如下所示:

<label>
   <input type="checkbox" [checked]="checkAllSelected()" 
         (click)="selectAll($event.target.checked)"/>Select all
</label>
<button (click)="unselectAll($event.target.checked)">Unselect All</button>

我们需要将复选框的状态传递到模板中,然后根据其状态来判断是全选还是取消全选:

selectAll(isChecked) {
  if isChecked 
     this.form.controls.unitArr.controls.map(x => x.patchValue(true))
  else
     this.form.controls.unitArr.controls.map(x => x.patchValue(false))
}

当用户点击未选中按钮时:
unselectAll() {
  this.form.controls.unitArr.controls.map(x => x.patchValue(false))
}

示例: http://plnkr.co/edit/O194WEimjf3XzfiIrWF0?p=preview


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