【问题标题】:How to get the value for Control inside FormArray in Angular while displaying record for patchValue operation显示patchValue操作记录时如何在Angular中的FormArray中获取Control的值
【发布时间】:2023-11-01 04:38:01
【问题描述】:

我一直在以角度反应形式使用 FormArray,在我尝试执行 patchValue() 操作之前一切正常。

在这里,我尝试编辑 projectForm。在表单中,您可以添加来自<select> <option> </option> </select> 的多个开发者。选项字段中的值来自数据库,用户可以根据需要添加任意数量的开发人员

问题的简码版本如下:
project.component.ts

projectForm: FormGroup

constructor(private fb: FormBuilder, private projectService: ProjectService, private developerService: DeveloperService){ }

ngOnInit() {
    this.developerService.getDeveloper().subscribe((data) => {
        this.developers = data;
    }, (error) => {
        console.log(error)
    } 
    });

    this.projectForm = this.fb.group({
        project_name: [''],
        devs: this.fb.array([this.buildDevs()]),
    })
    this.editProject();
}

buildDevs(): FormGroup {
    return this.fb.group({
      developer: ['', Validators.required]
    });
  }

displayProject(id: number) {
    this.projectService.getProjectDetail(id).subscribe(
        (project) => this.editProject(project),
        (error) => console.log(error)
    )
}

editProject(project){
    this.projectForm.patchValue({
       project_name: project.project_name, 
    });
    this.projectForm.setControl('devs', this.fb.array(project.developer || []));
}

ProjectService 正在响应正确的项目响应。那里没有错。
Addupdate 帖子需要以相同的形式完成,并且添加形式工作正常。 `project.component.html'

<form [formGroup]="projectForm">

    <label>Name: </label>
    <input type="text" formControlName="project_name">

    <label> Developers: </label>
    <div formArrayName="devs">
        <div *ngFor="let d of projectForm.controls.devs.controls; let i = index" [formGroupName]="i">
             <select formControlName="developer" *ngIf="developers">
               <option *ngFor="let dev of developers" value="{{ dev.id }}">{{ dev.user.username }}
               </option> 
             </select>   
        </div>
    </div>
</form>

Following error in the console is present in the response whenever I visit the project edit route

选项字段编号与要编辑的项目关联的开发人员数量完全相同,但选项中未显示开发人员的用户名。
ERROR Error: Cannot find control with path: 'devs -&gt; 0 -&gt; developer'
ERROR Error: Cannot find control with path: 'devs -&gt; 1 -&gt; developer' so on ... as the number of developer ...
任何帮助都将不胜感激,因为我是 Angular 的新手,并尝试了我能做的所有可能的选择。谢谢。

【问题讨论】:

  • 在 HTML projectForm.controls.devs.controls 中替换为“devs.controls”。如果您为 stackblitz 提供此类查询,这将很有用。它将帮助其他开发人员快速发现问题并为您更快地解决问题。

标签: angular angular-reactive-forms angular8


【解决方案1】:

我使用了@rxweb/reactive-form-validatorspatchModelValue方法,它将根据提供的服务器JSON对象或模型对象更新FormGroup内的FormControl的值。它将更新来自 FormGroup 的特定 FormControl 的值。您可以在编辑项目 api 调用期间传递 project.developer。

export class UserComponent implements OnInit {
    userInfoFormGroup: RxFormGroup

    constructor(
        private formBuilder: RxFormBuilder    ) { }

    ngOnInit() {
      this.userInfoFormGroup = <RxFormGroup>this.formBuilder.group({      
          devs:[
          {
            developer:['',Validators.required]
          }]
        });
    }
 getFormArray(){
      let formarray = this.userInfoFormGroup.controls.devs as FormArray;
      return formarray.controls;
    }

    editProject()
    {
          this.userInfoFormGroup.patchModelValue( {
                devs: [{ developer: "John" }] });
    }
}

你只需要在你的组件中导入RxFormBuilder,在你的应用模块ts中导入RxReactiveFormsModule

请参考working example

【讨论】:

  • 我是 Angular 的新手,我对 patchModelValue 不太了解,在遵循另一个答案后,我的问题现在得到了解决。感谢您的帮助,谢谢:)
【解决方案2】:

在使用patchValue之前,您需要使用所需数量的控件初始化FormArray

根据您的代码,假设project.developer 是这种形式的Array of Objects

[{developer: "dev1"},{developer: "dev2"},{developer: "dev3"}]
  editProject(project) {
    const devs = this.projectForm.get("devs") as FormArray;
    devs.clear();
    project.developer.forEach(d => devs.push(this.buildDevs()));
    this.projectForm.patchValue({
      project_name: project.project_name,
      devs: project.developer
    });
  }

【讨论】:

  • 我在&lt;select&gt; &lt;/select字段中使用这个并且使用这个解决方案,&lt;select&gt; &lt;/select&gt;字段的确切数量显示没有任何错误但没有选择值,我认为id的值需要从响应中显示选定的字段值。
  • 响应格式为[{id: 1, detail: 'detail-1'}, {id:2, detail: 'detail-2'}]
  • 然后将其转换为您的表单期望的格式,如下devs: project.developer.map(pd =&gt; ({developer: pd.id}))
  • 我很高兴它有帮助。祝你有美好的一天:)
最近更新 更多