【问题标题】:patchValue now working initializing FormArray valuespatchValue 现在正在初始化 FormArray 值
【发布时间】:2020-01-23 20:52:13
【问题描述】:

我有一张现金流量表。每个现金流都有可变数量的期间。 当我点击现金流时,我试图填充一个组件,以便可以编辑期间值。正在填充现金流名称和开始/结束日期。 我有一组句点,每个句点都有显示的文本框。

我无法在文本框中显示初始值。
我正在尝试让 patchValue 或 setValue 工作。

我已仔细查看了 SO 建议的 12 个问题。有人给了我一个尝试的想法,但最终并没有解决我的问题。

这里是 cashFlowDetailComponent.ts

 import { Component, OnInit , Input, Output, ElementRef} from '@angular/core';
import { ReactiveFormsModule, FormBuilder, FormGroup, FormArray, FormControl, ValidatorFn } from '@angular/forms';
import {cashFlow, cashFlowPeriod} from '../cashflow'
import { IMyDpOptions, IMyDateModel, IMyDate } from 'mydatepicker';


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



  myFormGroup: FormGroup;
  myCashFlow: cashFlow;


  constructor(private fb: FormBuilder) { 

   }

    //called by parent component when cashFlow is clicked.
  buildForm(cf_: cashFlow): void {
    //return;
    this.myFormGroup = null;
    this.myCashFlow = cf_;
    if (cf_ == null) { return;}
    const a :FormArray = this.fb.array([]); 



    this.myCashFlow.periods.forEach(cfp => {

      a.push(this.cfpGroup(cfp));
    })

     //set up the form w/ header controls, add in the periods array
    this.myFormGroup = this.fb.group({
      cashFlowName: this.myCashFlow.cashFlowName,
      startDate: this.threePartDateFromDate( this.myCashFlow.startDate),
      endDate: this.threePartDateFromDate( this.myCashFlow.endDate),
      periods:a
    });



       this.myFormGroup.controls['periods'].controls[i].controls['value1'].setValue(this.myCashFlow.periods[i].value1);
    //}



  }//end of buildform

  //return a simple FormGroup , this will cause 'periods' to be an FormArray of FormGroups,  each w/ 1 control
  cfpGroup(cfp_ : cashFlowPeriod) :FormGroup{
    const g : FormGroup = this.fb.group({
      value1: cfp_.value1
    });
    //  g.patchValue(cfp_);   //suggested in one of the related SO questions. No Joy.
    return g;
  }


  //needed to patch the myDatePicker. It works, it may not be pretty or efficient... 
  threePartDateFromDate(d_: string): any {
    const date_ = new Date(d_);

    return {
      date: {
        year: date_.getFullYear(),
        month: date_.getMonth()+1,
        day: date_.getDate()}
    }

  }
}

这是我的模板

    <div *ngIf="myCashFlow && myFormGroup" [formGroup]="myFormGroup">

      <table style="margin:7px 7px 7px 7px">
            <tr>
          <td class="fieldLabel">Cash Flow Name</td>
          <td>
            <input type="text"
                   formControlName="cashFlowName"
                   style="width:175px;" />
          </td>
        </tr>


      </table>




   <table border="1">
    <tr>
      <td *ngFor="let cfp of myCashFlow.periods,let i=index">{{cfp.periodName}}</td>
    </tr>
    <tr>
      <td *ngFor="let cfp of myCashFlow.periods, let i=index" style="padding:7px;">
        <input type="text"
               [id]="cfp.periodName"
               style="width:35px;" />
      </td>
    </tr>
  </table>

</div>

【问题讨论】:

  • 你认为有人会想要浏览这么多代码吗?您应该在 stackblitz/plunkr 上创建一个简化的可重现示例

标签: angular typescript reactive-forms formarray


【解决方案1】:

感谢 saksham 建议我将其放入 stackblitz
似乎每天都学习一项新技能

请在此处找到。 https://stackblitz.com/edit/angular-qcjxri

通过仔细比较 stackblitz 代码和 vic rubba 的这个示例,我能够确定问题所在 https://dev.to/crazedvic/using-patchvalue-on-formarrays-in-angular-7-2c8c

  1. 封装 ngFOR 的我需要一个 formArrayName="periods" 无括号
  2. 我需要一个[formGroupName]="periodIndex",它是for 的索引。如果有人可以解释这一点,我将不胜感激。那是神奇的最后一块。
  3. 需要的formControlName="value1" 没有括号

在过去的两天里,我阅读了很多关于 FormGroup 和 FormArray 和 patchValue 的文章。不知何故,第 2 点和第 3 点已经引起了我的注意。我有兴趣回去再读一遍那些文章。

我希望这对某人有所帮助。

整个 HTML 模板在 stackBlitz 上,但我将其发布在这里,以便您可以看到我的 3 点在上下文中的位置。

  <table border="1">
    <tr>
      <td *ngFor="let cfp of myCashFlow.periods,let i=index">{{cfp.periodName}}</td>
    </tr>
    <tr  formArrayName="periods">
      <td *ngFor="let item of myFormGroup.get('periods').controls, let periodIndex=index"
          style="padding:7px;"
          [formGroupName]="periodIndex">
        <input type="text"
               formControlName="value1"
               style="width:35px;" />
      </td>
    </tr>
  </table>

【讨论】:

  • 关于括号与否,认为如果你使用brackets,Angular认为另一边是一个“表达式”并尝试评估,例如[formArrayName]="periods",Angular 在您的组件中查找变量“句点”。关于formGroupName,你有一个formGroup数组,你需要指明formGroup,你可以使用“索引”[formGroupName]="periodIndex"或者甚至使用for和formGroup的变量[formGroup]="item"来指明。关于 patchValue,pathValue 不会向您的 formArray 添加(或删除)元素,只需填写值
猜你喜欢
  • 2017-05-18
  • 2021-09-24
  • 2018-12-20
  • 2020-04-26
  • 2020-04-20
  • 1970-01-01
  • 2019-12-19
  • 2019-06-22
  • 1970-01-01
相关资源
最近更新 更多