【问题标题】:Angular + Material - How to handle multiple checkboxes with formgroupAngular + Material - 如何使用表单组处理多个复选框
【发布时间】:2018-03-26 17:33:08
【问题描述】:

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

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 数组中。即使复选框被选中。

【问题讨论】:

    标签: angular angular-material


    【解决方案1】:

    您应该手动将控件添加到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

    【讨论】:

    • 从 stackblitz 这不是我想要的,当我真正想要兴趣的值时,它会返回一个真假值数组。因为 true 和 false 值实际上并没有告诉我选择了什么兴趣,因为关键是索引。我什至不知道为什么要在此处添加索引?对于本来应该很简单的事情,这似乎是一个过于复杂的解决方案。
    • 所以在那个 stackbltiz 示例中,它应该返回一个兴趣数组,其值为interest1,interest2,interest3 而不是 0:true 1:true 2:true
    • 您尝试提交表单了吗?看控制台
    • @yurzui 如何在该示例中选择所有复选框?你有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 2020-12-21
    • 2018-03-18
    • 2020-01-29
    相关资源
    最近更新 更多