Angular 角度2使用FormBuilder访问嵌套FormArray
首先,我从Angular 2开始,尝试构建一个嵌套表单并验证它 这是我的ts文件的一部分:Angular 角度2使用FormBuilder访问嵌套FormArray,angular,typescript,angular2-forms,Angular,Typescript,Angular2 Forms,首先,我从Angular 2开始,尝试构建一个嵌套表单并验证它 这是我的ts文件的一部分: ngOnInit() { this.myForm = this.formBuilder.group({ projects: this.formBuilder.array([ this.initProjects() ]) }); } initProjects(): any { return this.formBuilder.group({ name: [''
ngOnInit() {
this.myForm = this.formBuilder.group({
projects: this.formBuilder.array([
this.initProjects()
])
});
}
initProjects(): any {
return this.formBuilder.group({
name: ['', [Validators.required, Validators.minLength(3)]],
some_array: this.formBuilder.array([
this.formBuilder.group({
name: ['', Validators.required],
attr: ['', Validators.required],
some_id: [1, Validators.required]
})
])
});
}
addProject(): void {
const control = < FormArray > this.myForm.controls['projects'];
control.push(this.initProjects());
}
正如你所看到的,我有一些数组叫做projects,每个数组中有一个数组
所以问题是我无法验证某个数组的每个控件
实际上,我得到了以下错误:
原始异常:找不到路径为:'projects->0->controls.some\u array.controls.name的控件
PS:我已经试着把它放在一个div中,如下所示:
但我也犯了一个错误:
找不到路径为“项目->某些数组”的控件
提前谢谢。任何帮助都将不胜感激。请尝试以下HTML:
<div formArrayName="options">
<ion-row *ngFor="let option of addProductForm.controls.options.controls; index as i;">
<ion-col no-padding [formGroupName]="i">
<ion-item>
<ion-label floating>Name</ion-label>
<ion-input type="text" [formControlName]="option_name"></ion-input>
</ion-item>
</ion-col>
</ion-row>
</div>
诺梅雷奎里多
提交
表单值:
{{myForm.value | json}
在嵌套formControlName周围使用括号时,我遇到了同样的问题。例如(这是错误的):
名称
formControlName=“option_name”必须不带括号和嵌套数组。以下是我在angular6中测试并完美运行的代码示例: app.component.ts:
从“@angular/core”导入{Component,OnInit};
从'@angular/forms'导入{FormGroup,FormArray,FormBuilder,Validators,FormControl,NgControl};
@组成部分({
选择器:'应用程序根',
templateUrl:“./app.component.html”
})
导出类AppComponent实现OnInit{
proxyMedia:FormArray;
formGroup:formGroup;
建造师(
公共表单生成器:表单生成器
) {}
恩戈尼尼特(){
this.formGroup=this.formBuilder.group({
测试名称:['',[Validators.required]],
测试:this.formBuilder.array([
this.initTestsForm()
])
});
}
initTestsForm():任何{
返回此.formBuilder.group({
测试编号:“”,
类别:'',
响应:this.formBuilder.array([
this.initElement('responses'))
])
});
}
initElement(elementName:string):FormGroup{
如果(elementName==='proxy\u media'){
返回此.formBuilder.group(
{
前缀:“前缀”,
confid:“confid”
}
);
}else if(elementName==='tests'){
返回此.formBuilder.group({
test_num:['test_num',[Validators.required,Validators.minLength(2)],
分类:['categorie',[Validators.required,Validators.minLength(2)],
响应:this.formBuilder.array([
this.initElement('responses'))
])
});
}else if(elementName==='responses'){
返回此.formBuilder.group({
code_response:['code_response',Validators.required],
日志级别:[“日志级别”,验证器。必需]
});
}
}
addElement(formGroup:formGroup,elementName:string):void{
const control=formGroup.controls[elementName];
control.push(this.initElement(elementName));
}
removeElement(formGroup:formGroup,elementName:string,index:number):void{
const control=formGroup.controls[elementName];
控制。移除(索引);
}
onSubmit(o:任何){
控制台日志(o);
}
调试(数据:任意){
console.warn('debug:data');
控制台。警告(数据);
控制台。警告(“停止”);
}
}
app.component.html:
可用性测试
测验
测试编号#{{testIndex}
响应
HTTP响应{{testIndex}.{{responseIndex}
需要代码响应
删除响应
添加响应
移除测试
添加测试
提交
在底部添加以下代码以进行调试:
表单值:
{{formGroup.value | json}
如果没有数组,但嵌套了fromGroup,那么如何显示错误消息。
form value:
{
"projects": [
{
"name": "",
"some_array": [
{
"name": "",
"attr": "",
"some_id": 1
}
]
},
{
"name": "",
"some_array": [
{
"name": "",
"attr": "",
"some_id": 1
}
]
}
]
}
<form [formGroup]="myForm" novalidate (ngSubmit)="onSubmit(myForm)">
<div formArrayName="projects">
<div [formGroupName]="i" *ngFor="let project of myForm.controls.projects.controls; let i = index">
<md-input placeholder="Name" formControlName="name"></md-input>
<div formArrayName="some_array">
<div [formGroupName]="x" *ngFor="let some_obj of project.controls.some_array.controls; let x = index">
<div>
<md-input placeholder="Nome" formControlName="name"></md-input>
<small *ngIf="!some_obj.controls.name.valid">Nome é requerido</small>
</div>
<md-input type="number" placeholder="Cost" formControlName="attr" required></md-input>
</div>
</div>
</div>
</div>
<button type="submit" md-raised-button color="primary" [disabled]="!myForm.valid">Submit</button>
</form>
<pre>form value: <br>{{myForm.value | json}}</pre>
<div formArrayName="options">
<ion-row *ngFor="let option of addProductForm.controls.options.controls; index as i;">
<ion-col no-padding [formGroupName]="i">
<ion-item>
<ion-label floating>Name</ion-label>
<ion-input type="text" [formControlName]="option_name"></ion-input>
</ion-item>
</ion-col>
</ion-row>
</div>
<pre>
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormArray, FormBuilder, Validators, FormControl, NgControl } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
proxyMedia: FormArray;
formGroup: FormGroup;
constructor(
public formBuilder: FormBuilder
) {}
ngOnInit() {
this.formGroup = this.formBuilder.group({
test_name: ['', [Validators.required]],
tests: this.formBuilder.array([
this.initTestsForm()
])
});
}
initTestsForm(): any {
return this.formBuilder.group({
test_num: '',
categorie: '',
responses: this.formBuilder.array([
this.initElement('responses')
])
});
}
initElement(elementName: string): FormGroup {
if(elementName === 'proxy_media') {
return this.formBuilder.group(
{
prefixe: 'prefixe',
confid: 'confid'
}
);
} else if(elementName === 'tests') {
return this.formBuilder.group({
test_num: ['test_num', [Validators.required, Validators.minLength(2)]],
categorie: ['categorie', [Validators.required, Validators.minLength(2)]],
responses: this.formBuilder.array([
this.initElement('responses')
])
});
} else if(elementName === 'responses') {
return this.formBuilder.group({
code_response: ['code_response', Validators.required],
log_level: ['log_level', Validators.required]
});
}
}
addElement(formGroup: FormGroup, elementName: string): void {
const control = < FormArray > formGroup.controls[elementName];
control.push(this.initElement(elementName));
}
removeElement(formGroup: FormGroup, elementName: string, index: number): void {
const control = <FormArray>formGroup.controls[elementName];
control.removeAt(index);
}
onSubmit(o: any) {
console.log(o);
}
debug(data: any) {
console.warn('debug: data ');
console.warn(data);
console.warn('stop');
}
}
</pre>
<b>app.component.html:</b>
<h1> Avaibility tests</h1>
<form [formGroup]="formGroup" novalidate (ngSubmit)="onSubmit(formGroup)">
<input placeholder="Test name" formControlName="test_name">
<hr>
<h3>Tests</h3>
<div formArrayName="tests">
<div [formGroupName]="testIndex" *ngFor="let test of formGroup.controls.tests.controls; let testIndex = index">
<h2> Test number #{{testIndex}}</h2>
<input placeholder="Test number" formControlName="test_num">
<input placeholder="Category" formControlName="categorie">
<h3>Responses</h3>
<hr>
<div formArrayName="responses">
<div [formGroupName]="responseIndex" *ngFor="let response of test.controls.responses.controls; let responseIndex = index">
<div>
<h4> HTTP Response #{{testIndex}}.{{responseIndex}}</h4>
<input placeholder="Code response" formControlName="code_response">
<small *ngIf="!response.controls.code_response.valid">code response required</small>
<input placeholder="Log level" formControlName="log_level">
</div>
<button type="button" (click)='removeElement(test,"responses",responseIndex)'>Remove Response</button>
</div>
</div>
<hr>
<button type="button" (click)="addElement(test,'responses')">Add Response</button>
<br><br>
<button type="button" (click)='removeElement(formGroup,"tests",testIndex)'>Remove Test</button>
</div>
</div>
<hr>
<button type="button" (click)='addElement(formGroup,"tests")'>Add Test</button>
<hr>
<button type="submit" md-raised-button color="primary" [disabled]="!formGroup.valid">Submit</button>
</form>
<br><br>
</pre>
<b>Add this code at the bottom to debug:</b>
<pre>form value: <br>{{formGroup.value | json}}</pre>