Angular + Material - 如何使用formgroup处理多个复选框

时间:2017-10-14 20:55:44

标签: angular angular-material

我有一份我从后端获得的兴趣列表。我希望用户能够选择他们想要的兴趣。我将仅存储他们在数据库中检查的兴趣,并在加载页面时预先填充。但首先我需要获得用户选择的这些兴趣。

interest.component.ts

export class InterestsComponent implements OnInit {

  interestFormGroup : FormGroup
  interests:any;
  selected: any;


  constructor(public interestService: InterestService, private formBuilder: FormBuilder,
  ) { }

  ngOnInit() {

    this.interestFormGroup = this.formBuilder.group({
      interests: this.formBuilder.array([])
    });


    this.interestService.all().subscribe((res) => {

      this.interests = res;

    });

  }

  change() {
    console.log(this.interestFormGroup.value);
  }

}

interest.component.html

<div id="interest">

    <div class="interest-list">

        <form [formGroup]="interestFormGroup">
            <div *ngFor="let interest of interests" >
                <mat-checkbox class="example-margin" formNameArray="interests" (change)="change()">{{interest}}</mat-checkbox>
            </div>
        </form>

    </div>

</div>

在我更改事件的console.log中,它显示没有值被添加到interestFormGroup中的interests数组。甚至勾选复选框。

1 个答案:

答案 0 :(得分:14)

您应该手动向FormArray添加控件,如:

this.interests = res;
const formArray = this.interestFormGroup.get('interests') as FormArray;
this.interests.forEach(x => formArray.push(new FormControl(false)));

然后按如下方式更改模板:

<form [formGroup]="interestFormGroup" (ngSubmit)="submit()">
   <ng-container formArrayName="interests">
      <div *ngFor="let interest of interests; let i = index" >
         <mat-checkbox class="example-margin" [formControlName]="i">
           {{interest}}
         </mat-checkbox>
      </div>
   </ng-container>
   <button>Submit</button>
</form>

当您提交表单时,您需要将FormArray值转换为您想要的结果:

submit() {
  const result = Object.assign({}, 
    this.interestFormGroup.value, { 
      interests: this.interests
        .filter((x, i) => !!this.interestFormGroup.value.interests[i])});

  console.log(result);
}

备用解决方案是监听change事件并手动添加和删除FormArray的值:

<div *ngFor="let interest of interests; let i = index" >
   <mat-checkbox class="example-margin" 
                (change)="onChange($event)" [value]="interest">{{interest}}</mat-checkbox>
</div>

onChange(event) {
  const interests = <FormArray>this.interestFormGroup.get('interests') as FormArray;

  if(event.checked) {
    interests.push(new FormControl(event.source.value))
  } else {
    const i = interests.controls.findIndex(x => x.value === event.source.value);
    interests.removeAt(i);
  }
}

<强> Stackblitz example