我有一个动态表单数组,如果我单击添加联系人按钮,它将添加动态表单字段后,我尝试验证表单字段(validator.required,validator.pattern等..)及其工作正常。
当我试图在html视图中显示以下错误消息时
<md-error *ngIf="myForm.controls.myContactArray.controls['name'].hasError('required')">
Email is <strong>required</strong>
</md-error>
收到以下错误消息
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>
打字稿
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)
}
}
答案 0 :(得分:5)
因此,根据您的评论,我了解您希望一次只显示一条错误消息。
但是,情况是,您需要指定要应用验证错误的表单组。与
myForm.controls.myContactArray.controls['name'].hasError('required')
您试图在表单数组中指向表单控件name
,而不是指向表单组内的任何特定表单控件。
所以,你可以这样做。使用您在formarray中命名每个表单组的myGroup
,然后在该组中有一个嵌套表单组,即myGroupName[rowIndex]
。因此,您的验证错误可能如下所示:
<md-error *ngIf="!myGroup.controls[myGroupName[rowIndex]].hasError('minlength', 'name')">
Name is required
</md-error>
答案 1 :(得分:2)
尝试使用
dotnet run -h
我最近遇到了一个奇怪的错误,所以如果你有一个参数错误,请尝试使用它
*ngIf="myForm.hasError('required', 'name')"