【问题标题】:Angular 2 Form "Cannot find control with path"Angular 2 Form“找不到带有路径的控件”
【发布时间】:2017-02-02 10:15:57
【问题描述】:

我尝试制作一个动态表单(这样您就可以无限制地将项目添加到列表中),但不知何故,我的列表内容没有被发送,因为它找不到带有路径的控件:

找不到带有路径的控件:'list_items -> list_item'

我的组件:

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

  listForm: FormGroup;

  constructor(private nodeService: NodeService, private messageService: MessageService, private fb: FormBuilder,
                private listService: ListService) { 
    this.listForm = this.fb.group({
      title: ['', [Validators.required, Validators.minLength(5)]],
      list_items: this.fb.array([
        this.initListItem(),
        ])
    });
  }


  initListItem() {
    return this.fb.group({
      list_item: ['']
    });
  }
  initListItemType() {
    return this.fb.group({
      list_item_type: ['']
    });
  }

  addListItem() {
    const control = <FormArray>this.listForm.controls['list_items'];
    control.push(this.initListItem());
  }

模板(list.component.html):

<h2>Add List </h2>

<form [formGroup]="listForm" novalidate (ngSubmit)="addList(listForm)">
  <div class="form-group">
    <input type="text" class="form-control" formControlName="title" placeholder="Title">
  </div>

  <div formArrayName="list_items">
    <div *ngFor="let list_item of listForm.controls.list_items.controls; let i=index" class="panel panel-default">
      {{i + 1}}.) <input type="text" formControlName="list_item" placeholder="List Item" class="form-control">
    </div>
    <a (click)="addListItem()">Add List Item +</a>

  </div>

  <button type="submit">Submit</button>
</form>

标题工作正常,但我找不到导致错误的“formControlName”错误。

在此先感谢您对此问题的任何帮助。

更新我所做的更改 list.component.html

<h2>Add List </h2>

<form [formGroup]="listForm" novalidate (ngSubmit)="addList(listForm)">
  <div class="form-group">
    <input type="text" class="form-control" formControlName="title" placeholder="Title">
  </div>

  <div formArrayName="list_items">
    <div *ngFor="let list_item of listForm.controls.list_items.controls; let i=index" class="panel panel-default">
      {{i + 1}}.) <input type="text" formControlName="{{i}}" placeholder="List Item" class="form-control">
    </div>
    <a (click)="addListItem()">Add List Item +</a>

  </div>

  <button type="submit">Submit</button>
</form>

在我的组件中,我更改了构造函数和 addListItem 方法:

listForm: FormGroup;

  constructor(private nodeService: NodeService, private messageService: MessageService, private fb: FormBuilder,
                private listService: ListService) { 
    this.listForm = this.fb.group({
      title: ['', [Validators.required, Validators.minLength(5)]],
      list_items: this.fb.array([
          [''],
        ])
    });
  }

  addListItem() {
    const control = <FormArray>this.listForm.controls['list_items'];
    control.push(this.fb.control(['']));
    console.log(control)
  }

【问题讨论】:

    标签: angular typescript angular2-forms


    【解决方案1】:

    在您的 HTML 表单中应该有一个 formControlName 映射到您的组件文件。

    <div *ngFor="let list_item of [0,1,2]; let i=index" class="panel panel-default">
      {{i + 1}}.) <input type="text" formControlName="{{i}}" placeholder="List Item" class="form-control">
    </div>
    
    list_items: this.fb.array([
        [''], //0 points to this
        [''], //1 points to this
        [''] //2 points to this
    ])
    

    【讨论】:

    • 这不会干扰我试图实现的目标吗?我有我的“initListItem()”,它返回“list_item”,因此可以动态添加新表单。您对如何实现这一点还有其他建议吗?
    • 非常感谢您带领我朝着正确的方向前进。我将在主帖中发布我所做的更改:)!
    • @dowu 那真是太棒了:)
    • 更新了我在帖子中所做的更改;)!
    • @Manish 如果我希望我的formControlName 更具描述性(如item-{{i}}),我将如何在formbuilder 数组中匹配它?可能吗?我尝试将[''] 替换为{'item-0': ''} 以及其他一些东西,但没有奏效,我找不到这样的示例。
    【解决方案2】:

    我也遇到了这个错误,我通过初始化class(this.fb.array([])中的元素)的变量解决了这个问题。

    代码片段

        mobileNumbers: this.fb.array([this.fb.group(new MobileNumber('IN'))]),
    

    使用 MobileNumber 类的地方。

    export class MobileNumber{
        public country_code: string;
        public mobile_number: string;
        constructor($cc){
            this.country_code = COUNTRY_CODES[$cc];
        }
    }
    

    export class MobileNumber{
        public country_code = '';
        public mobile_number = '';
        constructor($cc){
            this.country_code = COUNTRY_CODES[$cc];
        }
    }
    

    【讨论】:

      【解决方案3】:

      请注意,如果您的 FormArray 包含其他 FormGroup 控件(其中包含 FormControl 的其他实例),您需要执行此操作才能访问每个 FormGroup 中的控件:

              <div *ngFor="let item of myFormArray.controls; let i=index">
                  <div formGroupName="{{i}}">
                      <input formControlName="myFormGroupSubControl1" />
                      <input formControlName="myFormGroupSubControl2" />
      

      【讨论】:

      • 我花了一个下午才知道 `[formGroupName]="i"` 是使用嵌套数组强制执行的。
      • 谢谢您的好先生。这就是我所缺少的!!控件容器上的 formGroupName。
      • 这很棘手,非常感谢为我节省了数小时的调试时间
      【解决方案4】:

      FormArray@stackblitz 的简单示例(以下要点)

      app.component.ts

      import { Component,OnInit } from '@angular/core';
      import { FormGroup, FormControl, FormArray, FormBuilder, Validators } from '@angular/forms';
      
      @Component({
        selector: 'my-app',
        templateUrl: './app.component.html',
        styleUrls: [ './app.component.css' ]
      })
      export class AppComponent implements OnInit {
        fg: FormGroup;
        constructor(private fb: FormBuilder){}
        ngOnInit() {
        this.fg = this.fb.group({
          address: this.fb.group({
            street: ['', Validators.required],
          }),
          aliases: this.fb.array([])
        });
        const fa = (this.fg.get('aliases')as FormArray);
        this.addNewAlias();
        }
        addNewAlias(){
          const fa = (this.fg.get('aliases')as FormArray);
          fa.push(this.fb.group({
            name: ['', Validators.required]
          }));
        }
        deleteAlias(i:number){
          const fa = (this.fg.get('aliases')as FormArray);
          fa.removeAt(i);
          if(fa.length===0) this.addNewAlias();
        }
      }
      

      app.component.html

      <form [formGroup]="fg" class="spaced">
        <h3>Nested in Group:</h3>
        <div formGroupName="address" class="spaced">
          <label>
            <input type="text" formControlName="street">
            valid: {{fg.get('address').get('street')?.valid}}
          </label>
        </div>
        <h3>Nested in Array:</h3>
        <div formArrayName="aliases" *ngFor="let alias of fg.get('aliases').controls; let i = index;" class="border">
          <div [formGroupName]="i">
            <label>
              Alias {{i+1}}:
              <input formControlName="name" placeholder="Item name">valid: {{alias.get('name')?.valid}}
            </label>
            <button type="button" (click)="deleteAlias(i)">X</button>
          </div>
        </div>
        <button type="button" (click)="addNewAlias()">add</button>
      </form>
      <div>form valid: {{fg?.valid}}</div>
      

      【讨论】:

      • formArrayName 这正是我想要的,谢谢
      【解决方案5】:

      你必须使用插值。

      代替:

          <div
            class="form-group"
            *ngFor="let hobbyControl of getControls(); let i = index">
            <input type="text" class="form-control" formControlName="i">
          </div>
      

      您必须使用带有“formControlName”的插值:

          <div
            class="form-group"
            *ngFor="let hobbyControl of getControls(); let i = index">
            <input type="text" class="form-control" [formControlName]="i">
          </div>
      

      如果您使用的是最新版本的 Angular,请确保在 TypeScript 文件中进行操作,而不是在网页中,如下面文件“app.component.ts”中所示:

        getControls() {
          return (<FormArray>this.signupForm.get('hobbies')).controls;
        }
      

      【讨论】:

        【解决方案6】:

        -> 在组件文件中添加FormArray

         //TO USE FormArray (set form1:any;)
         form1:any;
        
          hobbies: new FormArray([
             new FormControl()
          ])
        

        -> 向/从爱好中添加/删除控件

         addHobbies(){
           this.form1.get('hobbies').push(new FormControl());
         }
        
        removeHobbies(index:number){
           this.form1.get('hobbies').removeAt(index);
        }
        

        -> 模板文件

        <div formArrayName="hobbies">
           <label for="hobbies">Hobbies</label>
           <div *ngFor="let hobby of form1.get('hobbies').controls;index as i">
            <input type='text' id="hobbies" class="form-control" placeholder="hobbies" [formControlName]="i">
            <button type="button" (click)="removeHobbies(i)">remove</button>
          </div>
          <button type="button (click)="addHobbies()">Add</button> 
         </div>
        

        【讨论】:

          猜你喜欢
          • 2019-12-11
          • 2017-10-28
          • 2018-10-28
          • 1970-01-01
          • 2017-12-09
          • 2018-12-24
          • 1970-01-01
          • 2016-11-30
          • 1970-01-01
          相关资源
          最近更新 更多