angular - 如何使用反应式表单进行动态默认选中的复选框

angular - How to do dynamic default checked checkboxes with reactive forms

我有一个编辑个人资料表格。因为有动态复选框。如果用户更新了复选框一次,那么它应该选中默认值。

这是我的 ts 文件...

import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { ApplicantsService } from '@app/services/applicants.service';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {

  myForm: FormGroup;
  submitted = false;
 
  userid: any;
  
  skills: any;
  experience: any;
  applicant_skills: any;
  profile: any;
  states: any;
  cities: any;
  profilePicture: any;

  constructor(
    private formBuilder: FormBuilder,
    private applicantsService: ApplicantsService,
  ) { }

  ngOnInit(): void {
    
    this.userid = JSON.parse(localStorage.getItem('currentUser')).user_id;

    this.myForm = this.formBuilder.group({
      userid: [''],
      first_name: new FormControl({value: null, disabled: true}, Validators.required),
      last_name: new FormControl({value: null, disabled: true}, Validators.required),
      email: new FormControl({value: null, disabled: true}, Validators.required),
      mobile: ['', Validators.required],
      state: ['', Validators.required],
      city: ['', Validators.required],
      skills: this.formBuilder.array([], [Validators.required]),
    });
    
    this.applicantsService.getProfile(this.userid).subscribe( res => {
      this.profile = res.data[0];
      this.myForm.patchValue(this.profile); 
    })

    this.applicantsService.getApplicantskills(this.userid).subscribe( res => 
    {
      if(res && res.data)
      {
        this.applicant_skills = res.data;
        
        
      }
    })


  }


  // convenience getter for easy access to form fields
  get f() { return this.myForm.controls; }

 


  onCheckboxChange(e) {
    const checkArray: FormArray = this.myForm.get('skills') as FormArray;

    if (e.target.checked) {
      checkArray.push(new FormControl(e.target.value));
    } else {
      let i: number = 0;
      checkArray.controls.forEach((item: FormControl) => {
        if (item.value == e.target.value) {
          checkArray.removeAt(i);
          return;
        }
        i++;
      });
    }
  }

  onSubmit()
  {
      this.submitted = true;

      // stop here if form is invalid
      if (this.myForm.invalid) {
        console.log(this.myForm)
        return;
      }

      console.log("this.myForm.value", this.myForm.value);
      
  }

}

这是我的 html 页面。

<!-- Spinner -->
<ngx-spinner></ngx-spinner>

<section id="profile-form" class="bg-grey">
    <div class="container">
      <div class="row justify-content-center">
        <div class="col-lg-10 col-md-12">
          
          <h1 class="text-center">Update your profile</h1>

          <div class="form p-md-6">

              
              <form  [formGroup]="myForm" (ngSubmit)="onSubmit()">

                <div class="form-row">
                    <div class="form-group d-none">
                        <input type="text"  formControlName="userid" value={{userid}}>
                    </div>
                    <div class="form-group col-md-6">
                        <label for="linkedin">First Name</label>
                        <input type="text" class="form-control" formControlName="first_name" placeholder="First Name">
                    </div>
                    <div class="form-group col-md-6">
                        <label for="lastname">Last Name</label>
                        <input type="text" class="form-control" formControlName="last_name" placeholder="Last Name">
                    </div>
                </div>

                <div class="form-row">
                    <div class="form-group col-md-6">
                        <label for="linkedin">Email ID</label>
                        <input type="email" class="form-control" formControlName="email" placeholder="Email ID">
                    </div>
                    <div class="form-group col-md-6">
                        <label for="lastname">Cellphone Number</label>
                        <input type="text" class="form-control" formControlName="mobile" placeholder="Cellphone Number" [ngClass]="{ 'is-invalid': submitted && f.mobile.errors }" required>
                        <div *ngIf="submitted && f.mobile.errors" class="invalid-feedback">
                            <div *ngIf="f.mobile.errors.required">This field is required</div>
                        </div>
                    </div>
                </div>

                

                  
                  <div class="form-row">
                      <div class="button-group-pills text-center col-md-12" data-toggle="buttons">

                        <label class="btn btn-default" *ngFor="let skill of skills">
                            <input type="checkbox" formArrayName="skills" (change)="onCheckboxChange($event)" value={{skill.id}} [ngClass]="{ 'is-invalid': submitted && f.skills.errors }" required>
                            <div>{{skill.skill}}</div>
                        </label>
                        <div *ngIf="submitted && f.skills.errors" class="error">
                            <div *ngIf="f.skills.errors.required">This field is required</div>
                        </div>
                      </div>
                      
                  </div>



                  <div class="form-row justify-content-center text-center pt-4 pb-2">
                      <div class="col-md-8">
                          <button type="submit" class="btn btn-apply px-4">save profile</button>
                      </div>
                  </div>
              </form>
          </div>
              
        </div>

      </div>
    </div>
  </section>

请帮忙...................................... ..................................................... ..................................................... ..................................................... ..................................................... .........

您通过检查当前值是否在 checkArray 数组

中来切换 [checked]

将其包含在您的输入字段中

[checked]="checkArray.includes(skill.id)"

所以你的输入变成

    <input type="checkbox" formArrayName="skills" (change)="onCheckboxChange($event)" [checked]="checkArray.includes(skill.id)
 value={{skill.id}} [ngClass]="{ 'is-invalid': submitted && f.skills.errors }" required>

更新

如果您仅将技能的 id 推入数组,则上述方法会起作用。但是由于您要推送整个 skill 对象,您可以改为检查该对象。

[checked]="checkArray.includes(skill)"

   <input type="checkbox" formArrayName="skills" (change)="onCheckboxChange($event)" [checked]="checkArray.includes(skill)
 value={{skill.id}} [ngClass]="{ 'is-invalid': submitted && f.skills.errors }" required>

Sadique,我想你希望你的“技能”是一组值。我没有找到我在 ReactiveForms 中使用 ngModel 来管理复选框列表的 SO。最接近的是

想法是您没有 FormArray,只有 FormControl,并且您使用 [(ngModel)] 为 formControl 赋值。是的,一个 FormControl 可以存储一个数组,是的,即使你没有在 .html

中输入,也存在一个 FormControl
    <label class="btn btn-default" *ngFor="let skill of skills">
       <input type="checkbox" 
          [ngModelOptions]="{standalone:true}"
          <!--see that "is checked" if in the array you has the value-->
          [ngModel]="(myForm.get('skills').value || []).indexOf(skill.id)>=0" 
          <!--when change, we call to the function-->
          (ngModelChange)="onChange($event,skill.id)" >
           <div>{{skill.skill}}</div>
    </label>

  onChange(checked: boolean, id: number) {
    
    const control = this.myForm.get("skills"); //get the control
    let value = control.value || [];       //get the value, if null an empty array
    if (checked && value.indexOf(id) < 0)  //if we checked and it's not in the array
      value = [...value, id].sort((a, b) =>    //concatenate the value and sort
        this.skills.findIndex(f => f.id == a) >
        this.skills.findIndex(f => f.id == b)? 1: -1
      );
    if (!checked) value = value.filter(x => x != id);  //if not checked remove it

    control.setValue(value.length ? value : null);  //finally set value
                          //see that is nothing selected, give value null
                          //this make that we can use Validators.required
  }

the stackblitz