首页 > 解决方案 > 我正在尝试以角度将 formControlName 传递给子组件,但在绑定表单时遇到了一些问题,请查找以下代码片段

问题描述

data-table.html (parent component)

这是我将使用一些通用组件的父组件,我想将该组件绑定到反应形式。```</你好>-->

开始编辑,看看会发生什么神奇的事情 :)

<div class="example-container mat-elevation-z8">

  <form [formGroup]="userForm">
    <mat-table formArrayName="users" #table [dataSource]="dataSource">

      <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

      <!-- Position Column -->
      <ng-container matColumnDef="position">
        <mat-header-cell *matHeaderCellDef> No. </mat-header-cell>
        <mat-cell *matCellDef="let element;let rowIndex = index" [formGroupName]="rowIndex">
          <span *ngIf="!isEdit"> {{element.position}} </span>
          <span *ngIf="isEdit"><input type="text" formControlName="no"></span>
        </mat-cell>

      </ng-container>

      <!-- Name Column -->
      <ng-container matColumnDef="name">
        <mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
        <mat-cell *matCellDef="let element;let rowIndex = index" [formGroupName]="rowIndex">
          <span *ngIf="!isEdit"> {{element.name}} </span>
          <span *ngIf="isEdit">  <app-custom-dropdown [fieldControlName]="this.userForm.controls.users.controls[rowIndex].get('name').value" [fieldIndex]="rowIndex" 
          [fieldFormGroup]="userForm"></app-custom-dropdown></span>
        </mat-cell>

      </ng-container>

      <!-- Weight Column -->
      <ng-container matColumnDef="weight">
        <mat-header-cell *matHeaderCellDef> Weight </mat-header-cell>
        <mat-cell *matCellDef="let element;let rowIndex = index" [formGroupName]="rowIndex">
          <span *ngIf="!isEdit"> {{element.weight}}</span>
          <span *ngIf="isEdit"><input type="text" formControlName="weight"></span>
        </mat-cell>

      </ng-container>

      <!-- Symbol Column -->
      <ng-container matColumnDef="symbol">
        <mat-header-cell *matHeaderCellDef> Symbol </mat-header-cell>
        <mat-cell *matCellDef="let element;let rowIndex = index" [formGroupName]="rowIndex">
          <span *ngIf="!isEdit"> {{element.symbol}} </span>
          <span *ngIf="isEdit"><input type="text" formControlName="symbol"></span>
        </mat-cell>

      </ng-container>

      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
    </mat-table>
  </form>
  <p>{{userForm.value | json}}</p>
  <button mat-raised-button color="primary" (click)="onEdit()">Edit</button>
</div>
```

custom-dropdown.component.html (child component)

这是我从父组件获取 formGroup 和 formControl 并将其绑定到模板的通用组件,如建议的那样

```
<div [formGroup]="fieldFormGroup">
    <ng-select [items]="cities" appendTo="body" formControlName="fieldControlName" bindLabel="name" placeholder="Select city">
    </ng-select>
</div>
``

custom-dropdown.component.ts
```
import { Component, OnInit, Input } from "@angular/core";

@Component({
  selector: "app-custom-dropdown",
  templateUrl: "./custom-dropdown.component.html",
  styleUrls: ["./custom-dropdown.component.scss"]
})
export class CustomDropdownComponent implements OnInit {
  constructor() {}
  @Input() fieldControlName;
  @Input() fieldIndex;
  @Input() fieldFormGroup;
  cities = [
    { id: 1, name: "Hydrogen" },
    { id: 2, name: "Helium" },
    { id: 3, name: "Pavilnys", disabled: true },
    { id: 4, name: "Lithium" },
    { id: 5, name: "Oxygen" }
  ];

  ngOnInit() {
    console.log(this.fieldControlName);
    console.log(this.fieldIndex);
  }
}
```
when i am trying to execute this code i am getting the below error
**ERROR Error: Cannot find control with name: 'fieldControlName'
    at _throwError (forms.js:3357)
    at setUpControl (forms.js:3181)
    at FormGroupDirective.addControl (forms.js:7345)
    at FormControlName._setUpControl (forms.js:8070)
    at FormControlName.ngOnChanges (forms.js:7993)
    at checkAndUpdateDirectiveInline (core.js:31906)
    at checkAndUpdateNodeInline (core.js:44367)
    at checkAndUpdateNode (core.js:44306)
    at debugCheckAndUpdateNode (core.js:45328)
    at debugCheckDirectivesFn (core.js:45271)
**


Please help me in which part i am doing mistakes here..

标签: angularangular-materialfrontendangular-reactive-formsangular8

解决方案


您需要更改模板以使其成为属性绑定表达式,而不是字符串值赋值:

<div [formGroup]="fieldFormGroup">
    <ng-select [items]="cities" appendTo="body" [formControlName]="fieldControlName" bindLabel="name" placeholder="Select city">
    </ng-select>
</div>

formControlName="fieldControlName"这分配给formControlName属性"fieldControlName"字符串文字。

[formControlName]="fieldControlName"这将属性绑定formControlNamefieldControlName属性。

编辑: 修复formControlName模板中的绑定。您只需要传递 controlName 就足以使其工作。

<span *ngIf="isEdit">  <app-custom-dropdown fieldControlName="name" [fieldIndex]="rowIndex" 
          [fieldFormGroup]="userForm"></app-custom-dropdown></span> 

这次我们将使用字符串赋值而不是属性绑定。您不需要显式找到确切的控件来绑定它。

<mat-cell *matCellDef="let element;let rowIndex = index" [formGroupName]="rowIndex">

上面的行已经指定了formGroupName. 所以这个组件的子组件会知道它属于哪个 formGroum。


推荐阅读