Angular + Material - How to handle multiple checkb

2019-03-30 02:07发布

I have a list of interests i am getting from the backend. I want a user to be able to select the interests they want. I will store only the interests they checked in the DB and pre-populate when they load the page. But first i need to get these interests the user has selected.

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>

In my console.log on the change event it shows there is no values being added to the interests array within the interestFormGroup. Even tho the checkboxes are checked.

1条回答
女痞
2楼-- · 2019-03-30 02:44

You should add controls to FormArray manually like:

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

then change template as follows:

<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>

And when you will submit form you need to transform FormArray values to your desired result:

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

  console.log(result);
}

Alternative solution is listen change event and manually add and remove value to 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

查看更多
登录 后发表回答