【问题标题】:angular - How to do dynamic default checked checkboxes with reactive formsangular - 如何使用反应形式进行动态默认选中复选框
【发布时间】:2021-03-09 23:19:28
【问题描述】:

我有一个编辑个人资料表单。 for 具有动态复选框。如果用户更新了复选框,那么它应该检查默认值。

这是我的 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>

请帮助.................................................. ..................................................... ..................................................... ..................................................... ..................................................... .....................

【问题讨论】:

    标签: angular checkbox angular-reactive-forms


    【解决方案1】:

    您可以通过检查当前值是否在 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>
    

    【讨论】:

    • 不工作...我的 checkArray 结构如下所示,` CheckedArray = [ 0: { id: 1, Skill: "item1" }, 1: { id: 2, Skill: "item2 " }, ] `
    • 我已根据您的情况更新了答案。如果可行,请告诉我,如果不行,我可以向您展示使用管道的解决方案。干杯
    • 它显示 ERROR TypeError: Cannot read property 'includes' of undefined
    • 哦,我看到您的数组变量是静态的,并且每次复选框更改时都会被清除。您可以像 checkArray: any = [] 这样在构造函数之前声明 checkArray,然后在 onCheckboxChange(e) 函数中调用 this.checkArray 而不是声明 const checkArray。让我知道这是否清楚
    【解决方案2】:

    Sadique,我想您希望您的“技能”是一组值。我没有找到我在 ReactiveForms 中使用 ngModel 来管理复选框列表的 SO。最接近的是this another 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

    【讨论】:

    • 感谢您的回答...我的实际问题是,我必须动态检查复选框...如果有人选择了 2 个项目并保存,那么它应该一直检查...我期待你有问题..谢谢
    • 当您创建控件时,您可以赋予价值,例如myForm.get('skills').setValue([1,3]),或者当你创建表单控件时:myForm=new FormGroup({skill:new FormControl([1],Validators.required})。如果在您的“个人资料”中,“技能”的值是一个数组,那么您的 this.myForm.patchValue(this.profile); 应该是什么值或您的“个人资料”?
    猜你喜欢
    • 2020-01-15
    • 2019-10-04
    • 2020-01-11
    • 2020-02-29
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 2019-06-28
    相关资源
    最近更新 更多