反应形式多个复选框选择所有不起作用

时间:2019-02-17 04:19:27

标签: angular angular-reactive-forms reactive-forms

我是Angular中的Reactive Forms的新手。我的表单中有多个复选框数组。当用户单击“全选”按钮时,我需要选中所有复选框。在我的示例中,我想检查所有年龄列表值。当用户单击“全部取消选择”时,我要全部取消选择。我尝试过,但是没有用。

HTML

<form [formGroup]="myForm">
  <p>Language</p>
    <div *ngFor="let data of languages let i = index">
        <input type="checkbox" (change)="onChange(data.name, $event.target.checked)"> {{data.name}}<br>
    </div>

<p>Age List</p>
  <button (click)="checkAll()">Check all</button>
    <button (click)="deselectAll()">Deselect all</button>
  <div *ngFor="let data of ages let j = index">
        <input type="checkbox" (change)="onAgeChange(data.name, $event.target.checked)"> {{data.name}}<br>
    </div>
</form>

<pre>Form values: {{myForm.value | json}}</pre>

应用组件

  ages = [{ ageID: 100 ,name: "0 -10 years" }, {ageID: 200 ,name: "10 -20 years" }, {ageID: 300 ,name: "30 -40 years" }, { ageID: 400 ,name: "40 -50 years"  }]
  languages = [{ langID: 1 ,name: "English" }, {langID: 2 ,name: "Tamil" }, {langID: 3 ,name: "Hindi" }, { langID: 4 ,name: "French"  }]


  myForm: FormGroup;

  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.myForm = this.fb.group({
      userage: this.fb.array([]),
      userlanguage: this.fb.array([])
    });
  }

  onChange(language: string, isChecked: boolean) {
    const languageFormArray = <FormArray>this.myForm.controls.userlanguage;

    if (isChecked) {
      languageFormArray.push(new FormControl(language));
    } else {
      let index = languageFormArray .controls.findIndex(x => x.value == language)
      languageFormArray .removeAt(index);
    }
  }

  onAgeChange(age : string, isChecked: boolean) {
    const ageFormArray = <FormArray>this.myForm.controls.userage;

    if (isChecked) {
      ageFormArray.push(new FormControl(age));

    } else {
      let index = ageFormArray.controls.findIndex(x => x.value == age)
      ageFormArray.removeAt(index);
    }
  }


  checkAll(){
    const languageFormArray = <FormArray>this.myForm.controls.userlanguage;
    //console.log(this.myForm.controls['userage'])
 this.myForm.controls['userage'].setValue(
        this.myForm.controls['userage'].value
            .map(value => true)
    );
  }

这是我到目前为止尝试过的 https://stackblitz.com/edit/angular-butm3h?file=src%2Fapp%2Fapp.component.html

感谢任何人都可以给我支持。

2 个答案:

答案 0 :(得分:0)

我会做些不同的事情,而是创建一个FormArray年龄段的人。然后将它们切换为falsetrue。提交后,我们会过滤以下true复选框:

ngOnInit() {
  getAPIData().subscribe((...) => {
    // is ages coming from api? Then change accordingly!
    const ages = this.ages.map(x => this.fb.control(false))
    this.myForm = this.fb.group({
      userage: this.fb.array(ages),
    });
  })
}

// create a getter for easier access (not necessary)
get ageArr() {
  return this.myForm.get('userage') as FormArray;
}

checkAll() {
  this.ageArr.controls.map(value => value.setValue(true))
}

deselectAll() {
  this.ageArr.controls.map(value => value.setValue(false))
}

在模板中,我们迭代formarray而不是ages数组。还请记住将type="button"放在全选按钮上,然后取消选择所有按钮,否则默认情况下它们将被视为type="submit"

如果这是异步的,则最好在表单标签上设置一个*ngIf

<form *ngIf="myForm">
 <!-- -->
   <div formArrayName="userage" *ngFor="let age of ageArr.controls; let i = index">
     <input type="checkbox" [formControlName]="i"> {{ages[i].name}}
   </div>
</form>

然后,如前所述,只需在提交时过滤true值:

onSubmit() {
  const chosenAges = this.ageArr.value
    .map((age, i) => age ? this.ages[i].name : null)
    .filter(age => age !== null);
  console.log(chosenAges);
}

您的 StackBlitz

答案 1 :(得分:0)

好的,我们需要摆脱事件驱动模式,开始考虑数据驱动模式,这是Angular的优势。

您不想将其包装在def __init__(self, *args, **kwargs): choices = kwargs.pop("choices") super(FormAffiliateReport, self).__init__(*args, **kwargs) self.fields['referrals'].choices = choices 中。所有这些都会导致您尝试提交时产生回发,这与Angular是单页应用程序的观点背道而驰(请注意,在某些情况下,<Form>是合适的,即验证和仅在提交事件被拦截的情况下。)

我摆脱了您的表单组,并调整了HTML模板以遵循Angular数据绑定所采用的方法。我添加了<Form>的使用来将您的复选框绑定到基础数据,并为数据模型添加了[(ngModel)]属性。

请参见the Stackblitz

模板更改

isChecked

主要代码更改

<input type="checkbox" [(ngModel)]="data.isChecked" />

您的数据:

  checkAll(){
    this.ages.forEach(o => o.isChecked = true);
  }
  uncheckAll(){
    this.ages.forEach(o => o.isChecked = false);
  }
相关问题