Angular 2 Form“找不到带有路径的控件”
Posted
技术标签:
【中文标题】Angular 2 Form“找不到带有路径的控件”【英文标题】:Angular 2 Form "Cannot find control with path" 【发布时间】: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)
【问题讨论】:
【参考方案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>
【讨论】:
以上是关于Angular 2 Form“找不到带有路径的控件”的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2.0、Typescript 和“FORM_DIRECTIVES”模块