Angular 2 FormArray错误

时间:2018-01-15 17:38:16

标签: angular angular2-forms formarray

您好我想在我的Angular 2 Recipe应用程序中显示一些成分细节。我正在使用FormArray,但是当我运行并使用浏览器开发工具来调试我的代码时,我可以在Console选项卡上看到以下错误。我想知道是否有人可以向我解释问题是什么以及我需要做些什么来纠正它: -

RecipeIngredientsDetailsComponent.html:17 ERROR Error: Cannot find control with path: 's_ingredientDetails -> ingredient_name'
    at _throwError (forms.js:2385)
    at setUpControl (forms.js:2255)
    at FormGroupDirective.addControl (forms.js:6606)
    at FormControlName._setUpControl (forms.js:7256)
    at FormControlName.ngOnChanges (forms.js:7169)
    at checkAndUpdateDirectiveInline (core.js:12092)
    at checkAndUpdateNodeInline (core.js:13598)
    at checkAndUpdateNode (core.js:13541)
    at debugCheckAndUpdateNode (core.js:14413)
    at debugCheckDirectivesFn (core.js:14354)

下面是我的类型脚本代码: -

import { Component, Input, Output, EventEmitter, OnInit, ElementRef } from '@angular/core';
import { FormArray, FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
import { Observable } from 'rxjs/Observable';

import { Ingredient } from '../ingredient';
import { IngredientDetailService } from '../ingredient-detail.service';


@Component({
  selector: 'app-recipe-ingredients-details',
  templateUrl: './recipe-ingredients-details.component.html',
  styleUrls: ['./recipe-ingredients-details.component.css'],
  providers: [IngredientDetailService]
})

export class RecipeIngredientsDetailsComponent implements OnInit {

  create_recipe_ingredient_detail_form: FormGroup;
  ingredients_arr: Ingredient[] = [];

  // @Output will tell the parent component (AppComponent) that an event happened in this component
  @Output() show_read_recipes_event = new EventEmitter();

  constructor(
    private formBuilder: FormBuilder,
    private ingredientDetailService: IngredientDetailService

  ) {  }

  @Input()
  r_id: number;

  @Input()
  s_ingredients: Ingredient[];

  ngOnInit() {
    this.create_recipe_ingredient_detail_form = this.formBuilder.group({
      s_ingredientDetails: this.formBuilder.array(
        this.s_ingredients.map(x => this.formBuilder.group({
          ingredient_name: [x.ingredient_name, [Validators.required]],
          ingredient_quantity: ['', [Validators.required]],
          ingredient_comment: ['', [Validators.required]],
        }))
      )
    })
  }

  createRecipeIngredientDetails(): void {
    this.ingredientDetailService.createRecipeIngredientDetails(this.create_recipe_ingredient_detail_form.value)
      .subscribe(
        ingredientDetail => {
          console.log(ingredientDetail);

          this.show_read_recipes_event.emit(
            { title: "Recipe Ingredients details" }
          );
        },
        error => console.log(error)
      );
  }

  dude(){
    console.log(this.s_ingredients);
  }

}

以下是我的HTML: -

<div class="row">
    <div class="col-md-12">
      <form [formGroup]="create_recipe_ingredient_detail_form" (ngSubmit)="createRecipeIngredientDetails()">
        <table class="table table-hover table-responsive table-bordered">
          <tr>
            <th>
              Ingredient Name
            </th>
            <th>
              Quantity
            </th>
            <th>
              Comment
            </th>
          </tr>
          <tr formArrayName="s_ingredientDetails" *ngFor="let ingredient of create_recipe_ingredient_detail_form.get('s_ingredientDetails').controls; let i=index">
              <td>
                <div class="form-group">
                  <input name="ingredient_name" formControlName="ingredient_name" class="form-control" id="ingredient.ingredient_id" readonly />           
                </div>
              </td>
              <td>
                <div class="form-group">   
                  <input type="text" name="ingredient_qty" formControlName="ingredient_quantity" class="form-control" id="{{ingredient.ingredient_name}}" />
                </div>
              </td>
              <td>
                <div class="form-group">   
                  <input type="text" name="ingredient_cmt" formControlName="ingredient_comment" class="form-control" id="{{ingredient.ingredient_name}}" />
                </div>
              </td>
          </tr>
          <tr>
            <td>
              <input type="hidden" id="hidden_recipe_id" name="hidden_recipe_id" value="{{r_id}}" />             
            </td>
            <td></td>
            <td>
              <button type="submit" class="btn btn-primary">Create Recipe Ingredient Details</button>
            </td>
          </tr>
        </table>
      </form>
    </div>
  </div>

下面是在运行时显示我的表单的屏幕截图: -

enter image description here

2 个答案:

答案 0 :(得分:2)

它是因为你的表单数组包含表单组,并且它们由索引键入,你需要在模板中指定组名,这样angular就可以正确地将你的控件绑定到像这样的组

<tr formArrayName="s_ingredientDetails" *ngFor="let ingredient of create_recipe_ingredient_detail_form.get('s_ingredientDetails').controls; let i=index">
    <!--
        Not semantically correct to have a div here, but it will solve the problem.
    -->
  <div [formGroupName]='i'>
    <td>
      <div class="form-group">
        <input name="ingredient_name" formControlName="ingredient_name" class="form-control" id="ingredient.ingredient_id" readonly />           
      </div>
    </td>
    <td>
      <div class="form-group">   
        <input type="text" name="ingredient_qty" formControlName="ingredient_quantity" class="form-control" id="{{ingredient.ingredient_name}}" />
      </div>
    </td>
    <td>
      <div class="form-group">   
        <input type="text" name="ingredient_cmt" formControlName="ingredient_comment" class="form-control" id="{{ingredient.ingredient_name}}" />
      </div>
    </td>
  </div>
</tr>

此外,它是2018年,停止使用table来布置您的内容

答案 1 :(得分:0)

感谢Dummy的帮助。这是工作的HTML: -

<tr formArrayName="s_ingredientDetails" *ngFor="let ingredient of create_recipe_ingredient_detail_form.get('s_ingredientDetails').controls; let i=index">
            <ng-container [formGroupName]='i'>
                <td>
                  <div class="form-group">
                    <input name="ingredient_name" formControlName="ingredient_name" class="form-control" id="ingredient.ingredient_id" readonly />           
                  </div>
                </td>
                <td>
                  <div class="form-group">   
                    <input type="text" name="ingredient_qty" formControlName="ingredient_quantity" class="form-control" id="{{ingredient.ingredient_name}}" />
                  </div>
                </td>
                <td>
                  <div class="form-group">   
                    <input type="text" name="ingredient_cmt" formControlName="ingredient_comment" class="form-control" id="{{ingredient.ingredient_name}}" />
                  </div>
                </td>
            </ng-container>
          </tr>