如何显示动态表单数组的 md 错误消息?
[英] How to show md-error message for dynamic form array?
本文介绍了如何显示动态表单数组的 md 错误消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个动态表单数组,如果我单击添加联系人按钮,它将添加动态表单字段,然后我尝试验证表单字段(validator.required、validator.pattern 等)及其工作正常.
>
当我尝试在 html 视图中显示以下错误消息时
需要电子邮件;</md-错误>
收到以下错误消息
core.es5.js:1020 错误类型错误:无法读取未定义的属性hasError"在 Object.eval [as updateDirectives] (RegisterComponent.ngfactory.js:453)在 Object.updateDirectives (core.es5.js:12770)在 checkAndUpdateView (core.es5.js:12288)在 callViewAction (core.es5.js:12651)在 execEmbeddedViewsAction (core.es5.js:12609)在 checkAndUpdateView (core.es5.js:12289)在 callViewAction (core.es5.js:12651)在 execComponentViewsAction (core.es5.js:12583)在 checkAndUpdateView (core.es5.js:12294)在 callViewAction (core.es5.js:12651)
html
<md-card><button (click)="addColumn()" md-raised-button>添加联系人</button><小时><form [formGroup] = "myForm" (ngSubmit) = "save(myForm.value)" class="contact-form"><div formArrayName="myContactArray"><div *ngFor="let myGroup of myForm.controls.myContactArray.controls; let rowIndex = index" ><div [formGroupName]="rowIndex" class="make-rel"><div class="make-abs">Row {{rowIndex + 1 }}</div><!--rowIndex - 新创建表单的索引号--><button *ngIf="myForm.controls.myContactArray.controls.length"(click)="removeColumn(rowIndex)" class="make-abs removeRow" md-mini-fab><md-icon>close</md-icon></button><div [formGroupName]="myGroupName[rowIndex]"><div class="row"><div class="col-md-2 col-md-offset-1"><div class="form-group"><md-input-container class="example-full-width"><input mdInput placeholder="姓名" formControlName ="姓名"><md-error *ngIf="myForm.controls.myContactArray.controls['name'].hasError('required')">需要电子邮件;</md-错误></md-input-container>
<div class="col-md-2"><div class="form-group"><md-input-container class="example-full-width"><input mdInput placeholder="Email ID" formControlName ="email"></md-input-container>
<div class="col-md-2"><div class="form-group"><md-input-container class="example-full-width"><input mdInput placeholder="City" formControlName ="city"></md-input-container>
<div class="col-md-2"><div class="form-group"><md-input-container class="example-full-width"><input mdInput placeholder="电话" formControlName ="电话"></md-input-container>
<div class="col-md-2"><div class="form-group"><md-input-container class="example-full-width"><input mdInput placeholder="Mobile" formControlName ="mobile"></md-input-container>
<小时>
<button md-raised-button type="submit" *ngIf="myForm.controls.myContactArray.controls.length > 0" [disabled] = "!myForm.valid">提交</button></表单></md-card>
打字稿
import {Component,OnInit} from '@angular/core';从@angular/forms"导入 {FormControl,FormBuilder,FormGroup,FormArray,Validators};const EMAIL_REGEX =/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;const mobile =/06([0-9]{8})/;@成分({模块 ID:module.id,选择器:应用注册",templateUrl: './register.component.html',styleUrls: ['./register.component.css']})导出类 RegisterComponent 实现 OnInit {公共 myForm:FormGroup;myGroupName = ['firstForm'];newName: string = "dynamicRow";新列名:字符串;构造函数(私有_FormBuilder:FormBuilder){}ngOnInit() {this.myForm = this._FormBuilder.group({myContactArray: this._FormBuilder.array([this._FormBuilder.group({firstForm: this._FormBuilder.group({表单名称:['firstForm'],名称:['', Validators.compose([Validators.required, Validators.minLength(3)])],电子邮件:['', Validators.compose([Validators.required, Validators.pattern(EMAIL_REGEX)])],城市:['', Validators.compose([Validators.required])],电话:['', Validators.compose([Validators.required])],移动:['', Validators.compose([Validators.required,Validators.minLength(10), Validators.maxLength(10), Validators.pattern(mobile)])],})}),])});}insertIntoArray(columnName: any) {返回 this._FormBuilder.group({[columnName]: this._FormBuilder.group({表格名称:[列名称],名称:['', Validators.compose([Validators.required, Validators.minLength(3)])],电子邮件:['', Validators.compose([Validators.required, Validators.pattern(EMAIL_REGEX)])],城市:['', Validators.compose([Validators.required])],电话:['', Validators.compose([Validators.required])],移动:['', Validators.compose([Validators.required,Validators.minLength(10), Validators.maxLength(10), Validators.pattern(mobile)])],})})}randonFormName() {var newColumnName = "";const alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for (var i = 0; i <5; i++)newColumnName += alpha.charAt(Math.floor(Math.random() * alpha.length));返回新列名;}添加列(){this.newColumnName = this.randonFormName();const control = <FormArray>this.myForm.controls['myContactArray'];this.myGroupName.push(this.newColumnName);control.push(this.insertIntoArray(this.newColumnName));控制台日志(控制);}删除列(我:数字){const control = <FormArray>this.myForm.controls['myContactArray'];control.removeAt(i);this.myGroupName.splice(i, 1);}保存(值:任何){控制台日志(值)}}
解决方案
因此,从您的评论中,我了解到您希望一次只显示一条错误消息.
然而,您需要指定要应用验证错误的表单组.随着
myForm.controls.myContactArray.controls['name'].hasError('required')
您正试图指向表单数组中的表单控件 name
,而不是表单组中的任何特定表单控件.
这就是你要怎么做.使用 myGroup
您在 formarray 中命名每个表单组,然后在该组内有一个嵌套的表单组,即 myGroupName[rowIndex]
.因此,您的验证错误可能如下所示:
姓名为必填项</md-错误>
I have a dynamic form array, If i click add contact button it will add dynamic form field after that i tried to validate the form fields(validator.required, validator.pattern etc..) and its working fine.
When i tried to show below error message in html view
<md-error *ngIf="myForm.controls.myContactArray.controls['name'].hasError('required')">
Email is <strong>required</strong>
</md-error>
getting below error message
core.es5.js:1020 ERROR TypeError: Cannot read property 'hasError' of undefined
at Object.eval [as updateDirectives] (RegisterComponent.ngfactory.js:453)
at Object.updateDirectives (core.es5.js:12770)
at checkAndUpdateView (core.es5.js:12288)
at callViewAction (core.es5.js:12651)
at execEmbeddedViewsAction (core.es5.js:12609)
at checkAndUpdateView (core.es5.js:12289)
at callViewAction (core.es5.js:12651)
at execComponentViewsAction (core.es5.js:12583)
at checkAndUpdateView (core.es5.js:12294)
at callViewAction (core.es5.js:12651)
html
<div class="container-fluid">
<md-card>
<button (click)="addColumn()" md-raised-button>Add Contacts</button>
<hr>
<form [formGroup] = "myForm" (ngSubmit) = "save(myForm.value)" class="contact-form">
<div formArrayName="myContactArray">
<div *ngFor="let myGroup of myForm.controls.myContactArray.controls; let rowIndex = index" >
<div [formGroupName]="rowIndex" class="make-rel">
<div class="make-abs">Row {{rowIndex + 1 }}</div> <!--rowIndex - Index num of newly created form-->
<button *ngIf="myForm.controls.myContactArray.controls.length"
(click)="removeColumn(rowIndex)" class="make-abs removeRow" md-mini-fab><md-icon>close</md-icon></button>
<div [formGroupName]="myGroupName[rowIndex]">
<div class="row">
<div class="col-md-2 col-md-offset-1">
<div class="form-group">
<md-input-container class="example-full-width">
<input mdInput placeholder="Name" formControlName ="name">
<md-error *ngIf="myForm.controls.myContactArray.controls['name'].hasError('required')">
Email is <strong>required</strong>
</md-error>
</md-input-container>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<md-input-container class="example-full-width">
<input mdInput placeholder="Email ID" formControlName ="email">
</md-input-container>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<md-input-container class="example-full-width">
<input mdInput placeholder="City" formControlName ="city">
</md-input-container>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<md-input-container class="example-full-width">
<input mdInput placeholder="Phone" formControlName ="phone">
</md-input-container>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<md-input-container class="example-full-width">
<input mdInput placeholder="Mobile" formControlName ="mobile">
</md-input-container>
</div>
</div>
</div>
</div>
<hr>
</div>
</div>
</div>
<button md-raised-button type="submit" *ngIf="myForm.controls.myContactArray.controls.length > 0" [disabled] = "!myForm.valid">Submit</button>
</form>
</md-card>
</div>
TypeScript
import {Component,OnInit} from '@angular/core';
import {FormControl,FormBuilder,FormGroup,FormArray,Validators} from '@angular/forms';
const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const mobile = /06([0-9]{8})/;
@Component({
moduleId: module.id,
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
public myForm: FormGroup;
myGroupName = ['firstForm'];
newName: string = "dynamicRow";
newColumnName: string;
constructor(private _FormBuilder: FormBuilder) { }
ngOnInit() {
this.myForm = this._FormBuilder.group({
myContactArray: this._FormBuilder.array([
this._FormBuilder.group({
firstForm: this._FormBuilder.group({
formName: ['firstForm'],
name: ['', Validators.compose([Validators.required, Validators.minLength(3)])],
email: ['', Validators.compose([Validators.required, Validators.pattern(EMAIL_REGEX)])],
city: ['', Validators.compose([Validators.required])],
phone: ['', Validators.compose([Validators.required])],
mobile: ['', Validators.compose([Validators.required,Validators.minLength(10), Validators.maxLength(10), Validators.pattern(mobile)])],
})
}),
])
});
}
insertIntoArray(columnName: any) {
return this._FormBuilder.group({
[columnName]: this._FormBuilder.group({
formName: [columnName],
name: ['', Validators.compose([Validators.required, Validators.minLength(3)])],
email: ['', Validators.compose([Validators.required, Validators.pattern(EMAIL_REGEX)])],
city: ['', Validators.compose([Validators.required])],
phone: ['', Validators.compose([Validators.required])],
mobile: ['', Validators.compose([Validators.required,Validators.minLength(10), Validators.maxLength(10), Validators.pattern(mobile)])],
})
})
}
randonFormName() {
var newColumnName = "";
const alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 5; i++)
newColumnName += alpha.charAt(Math.floor(Math.random() * alpha.length));
return newColumnName;
}
addColumn() {
this.newColumnName = this.randonFormName();
const control = <FormArray>this.myForm.controls['myContactArray'];
this.myGroupName.push(this.newColumnName);
control.push(this.insertIntoArray(this.newColumnName));
console.log(control);
}
removeColumn(i: number) {
const control = <FormArray>this.myForm.controls['myContactArray'];
control.removeAt(i);
this.myGroupName.splice(i, 1);
}
save(value: any) {
console.log(value)
}
}
解决方案
So from your comment, I understand you want to show just one error message at a time.
However the situation is, you need to specify which form group you want to apply the validation errors. With
myForm.controls.myContactArray.controls['name'].hasError('required')
you are trying to point to a a form control name
in the form array, not to any specific form control inside a form group.
So here's how you would do it. Use the myGroup
you are naming each form group inside the formarray, and then you have a nested form group inside that group, i.e myGroupName[rowIndex]
. So your validation error could look like this:
<md-error *ngIf="!myGroup.controls[myGroupName[rowIndex]].hasError('minlength', 'name')">
Name is required
</md-error>
这篇关于如何显示动态表单数组的 md 错误消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文