简体   繁体   English

使用 angular 中的 patchValue 将值修补到复选框

[英]Patch values to checkbox using patchValue in angular

I'm trying to re-use my create-form to edit the values of the form.我正在尝试重新使用我的create-form来编辑表单的值。 My checkbox is working as per requirement while creating a form.我的复选框在创建表单时按要求工作。 When I click on edit form, the values aren't patching to my checkbox.当我单击编辑表单时,这些值不会修补到我的复选框。 Below is my code which I have tried:以下是我尝试过的代码:

<div class="form-row">
  <div class="form-group col-sm-6">
    <label>Authorized To</label>
    <br>
    <label *ngFor="let choice of authorized; let i=index">
      <input type="checkbox" [value]="choice" (change)="onCheckChange($event)" [checked]="checkedVal"
          formArrayName="authorized" type="checkbox[class.invalid]="! formGrowLicense.controls['authorized'].valid && formGrowLicense.controls['authorized'].touched ">
                            {{choice}}
     </label>
    <div *ngIf="!formGrowLicense.controls['authorized'].valid && (formGrowLicense.controls['authorized'].touched || isSubmitted)">
      <div class="invalid-feedback" style="display: block;">Please enter authorized to</div>
    </div>

  </div>
</div>

ts ts

authorized: any = ['CULTIVATE', 'HARVEST', 'PROCESS']; //displaying list of checkbox
constructor() {
  this.formGrowLicense = this.formBuilder.group({
      businessName: ['', Validators.required], 
      authorized: new FormArray([], [Validators.required])
       });
   } 
 getGrowLicense(id) {
    this.httpService.getGrowLicenseById(id).subscribe(
      response => {
        this.patchGrowLicense(response);
        this.checkedVal = response.authorisedTo; // tried storing response in this variable  ['CULTIVATE','HARVEST']
      },

      (err: any) => console.log(err)
    );
  }
patch(licenseObj){
    this.formGrowLicense.patchValue({
      businessName:licenseObj.companyName,
      authorized: licenseObj.authorisedTo, // here i'm getting response ['CULTIVATE','HARVEST']. Need to patch these two values as checked in checkbox
      });
    }

 onCheckChange(event) {
    this.formArray = this.formGrowLicense.get(
      'authorized'
    ) as FormArray;

    /* Selected */
    if (event.target.checked) {
      console.log(event.target.value);
      // Add a new control in the arrayForm
      this.formArray.push(new FormControl(event.target.value));
    } else {
      /* unselected */
      // find the unselected element
      let i = 0;

      this.formArray.controls.forEach((ctrl: FormControl) => {
        if (ctrl.value == event.target.value) {
          // Remove the unselected element from the arrayForm
          this.formArray.removeAt(i);
          return;
        }

        i++;
      });
    }
  }

You has an FormArray of FormControls that takes values true/false and received and array of strings among a fixed array, so first you need transform the array received in an array of true/false您有一个 FormControls 的 FormArray,它接受值 true/false 和接收的值以及固定数组中的字符串数组,因此首先您需要将接收到的数组转换为 true/false 数组

First approach第一种方法

First we are going to create a Form with a formArray.首先,我们将创建一个带有 formArray 的表单。 As always we can manage a form array we need to create a getter that return our formArray与往常一样,我们可以管理一个表单数组,我们需要创建一个 getter 来返回我们的 formArray

  //our getter formArray
  get authorizedArray()
  {
    return this.formGrowLicense.get('authorized') as FormArray
  }

  ngOnInit()
  { //we create the formArray
    this.formGrowLicense=new FormGroup({
      businessName:new FormControl(),
      authorized:new FormArray(this.authorized.map(x=>new FormControl(false)))
    })
  }

See that the way to create the formArray is using new FormArray(..here and array of formControls..) .看到创建 formArray 的方法是使用new FormArray(..here and array of formControls..) And the way to create the formArray of formControls is "mapping" each element of the array "this.autorized" to a FormControl.创建formControls的formArray的方法是将数组“this.autorized”的每个元素“映射”到FormControl。

To manage in a series of inputs we using this.html为了管理一系列输入,我们使用 this.html

<form [formGroup]="formGrowLicense">
    <input formControlName="businessName">
    <!--we use formArrayName in a div-->
    <div formArrayName="authorized">
        <!--we iterate over autorizedArray.controls
           remember our getter of the formArray? -->
        <div *ngFor="let control of authorizedArray.controls;let i=index">
            <!--we use [formControlName]=i -->
            <label><input type="checkbox"  [formControlName]="i">{{authorized[i]}}</label>
        </div>
    </div>
</form>

As always, we check if it's all ok using (only for check) in the.html与往常一样,我们在.html 中使用(仅用于检查)检查是否一切正常

<pre>
  {{formGrowLicense?.value|json}}
</pre>

See how we iterate over the formArrayControls, and use the index, to show in the label authorized[i]看看我们如何遍历 formArrayControls,并使用索引,在 label 中显示授权[i]

Well, We know yet how control a form array, so the next question: how we feed the formArray with the values?好吧,我们还知道如何控制表单数组,所以下一个问题:我们如何为 formArray 提供值?

Remember that we received some like, eg请记住,我们收到了一些喜欢,例如

{
  businessName:'my business name'
  authorized:['CULTIVATE', 'PROCESS']
}

when we received the value in data we can use some like当我们收到数据中的值时,我们可以使用一些类似

   this.formGroupLicense.patchValue(
    {
     businessName:data.businessName,
     authorized:this.authorized.map(x=>data.authorized.indexOf(x)>=0)
    }

See how transform the "data.authorize" and array with 0,1,2 or 3 elements in an array of 3 elements that takes values true or false了解如何在 3 个元素的数组中使用 0、1、2 或 3 个元素转换“data.authorize”和数组,该数组取值为 true 或 false

Well, the last work we need is, in submit, use the values of the formArray (eg [true,false,false] to get an array of strings好吧,我们需要做的最后一项工作是,在提交时,使用 formArray 的值(例如 [true,false,false] 来获取字符串数组

submit(form)
{
   if (form.valid)
   {
        const data={
           businessName:form.value.businessName
           authorize:form.value.authorized.map(
              (x,index)=>x?this.authorized[index]:null)
              .filter(x=>x)
        }
        console.log(data) //<--here we has the data we send to the service
   }
}

Yes, we map the [true,false,false] to ['CULTIVATE',null,null] and filter and only want elements that are not null ['CULTIVATE']是的,我们 map [true,false,false]['CULTIVATE',null,null]并过滤并且只想要不是 null ['CULTIVATE']元素

Well, use pathValue is ok but why we not create a function that return a formGroup with the data we want好吧,使用 pathValue 是可以的,但是为什么我们不创建一个 function 来返回一个带有我们想要的数据的 formGroup

createFormGroup(data:any=null)
{
    data=data||{businessName:null,authorize:[]}
    return new FormGroup({
      businessName:new FormControl(data.businessName),
      authorized:new FormArray(this.authorized
        .map(x=>new FormControl(data.authorized.indexOf(x)>=0)))
    })
}

So, when we received the data the only thing we need is use所以,当我们收到数据时,我们唯一需要的就是使用

  this.formGroupLicense=this.createFormGroup(data)

Second approach第二种方法

We has a form like我们有一个像

    this.formGrowLicense=new FormGroup({
      businessName:new FormControl(),
      authorized:new FormControl()
    })

YES.是的。 authorized is a FormControl that store an array.授权是一个存储数组的 FormControl。 If you see the material multi checked is this approach.如果看到材质多勾选就是这种方法。 For this you can check this SO with use a custom formControl.为此,您可以使用自定义 formControl 检查此SO Let me explain (I don't want a customFormControl)让我解释一下(我不想要 customFormControl)

We has an auxiliary array with two properties "name" and "value" we want to get some like eg我们有一个辅助数组,其中包含两个属性“名称”和“值”,我们希望得到一些类似的属性,例如

authorizedAux: any = [{name:'CULTIVATE',value:true}, 
                      {name:'HARVEST',value:false},
                      {name:'PROCESS',value:true}]

So we add a function所以我们添加了一个 function

  setAutorized(data: string[]) {
    this.authorizedAux = this.authorized.map(x => ({
      name: x,
      value: data.indexOf(x) >= 0
    }));
  }

And another function parse和另一个 function 解析

  parse() {
    const result=this.authorized
      .map((x, index) => (this.authorizedAux[index].value ? x : null))
      .filter(x => x);
    return result.length>0?result:null
  }

then we can has an html that use ngModel, ngModelChange and ngModelOptions to change the value of the FormControl然后我们可以有一个 html 使用 ngModel、ngModelChange 和 ngModelOptions 来更改 FormControl 的值

<form [formGroup]="form">
    <input formControlName="businessName">
        <div *ngFor="let control of authorizedAux">
            <label>
        <input type="checkbox"  
            [ngModel]="control.value"
            (ngModelChange)="control.value=$event;form.get('authorized').setValue(parse())"
            [ngModelOptions]="{standalone:true}"
      >{{control.name}}</label>
        </div>
</form>

Remember that, when received the data we need call to the function setAutorized请记住,当收到数据时,我们需要调用 function setAutorized

See the two approaches in the stackblitz查看stackblitz中的两种方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM