如何在 angular 2 中以动态形式响应验证消息
how to reactive validation messages in dynamic forms in angular 2
我正在学习 angular 2.
中的反应式动态形式
我想像 angular.io 食谱表单验证那样验证消息。
像这样:
this.heroForm.valueChanges
.subscribe(data => this.onValueChanged(data));
所以我订阅动态表单中的表单值更改
但是奇怪的事情发生了,比如:
我群里有两个地址,一个有效,两个无效。
所以错误信息应该是一个,但结果是两个!!
有人可以帮忙解决这个问题吗?
这里是run file
这是地址html和ts文件
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
moduleId: module.id,
selector: 'address',
templateUrl: 'address.component.html',
})
export class AddressComponent {
@Input('group')
public adressForm: FormGroup;
}
<div [formGroup]="adressForm">
<div class="form-group col-xs-6">
<label>street</label>
<input type="text" class="form-control" formControlName="street">
<small [hidden]="adressForm.controls.street.valid" class="text-danger">
Street is required
</small>
</div>
<div class="form-group col-xs-6">
<label>postcode</label>
<input type="text" class="form-control" formControlName="postcode">
</div>
</div>
这是应用
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormArray, FormBuilder, Validators } from '@angular/forms';
import { Customer } from '../model/customer.model';
@Component({
selector: 'customer-component',
templateUrl: 'customer.component.html',
})
export class CustomerComponent implements OnInit {
public customerForm: FormGroup;
constructor(private _fb: FormBuilder) { }
ngOnInit() {
this.customerForm = this._fb.group({
'name': ['', [Validators.required, Validators.minLength(5)]],
'addresses': this._fb.array([])
});
// add address
this.addAddress();
this.customerForm.valueChanges
.subscribe(data => this.onValueChanged(data));
this.onValueChanged(); // (re)set validation messages now
}
initAddress() {
return this._fb.group({
'street': ['', Validators.required],
'postcode': ['']
});
}
addAddress() {
const control = <FormArray>this.customerForm.controls['addresses'];
const addrCtrl = this.initAddress();
control.push(addrCtrl);
}
removeAddress(i: number) {
const control = <FormArray>this.customerForm.controls['addresses'];
control.removeAt(i);
}
onSubmit() {
}
onValueChanged(data?: any) {
const form = this.customerForm;
for (const field in this.formErrors) {
// clear previous error message (if any)
const control = form.get(field);
if (control instanceof FormArray) {
const fmArray = <FormArray>control;
console.log("from Array have count : " + fmArray.controls.length);
this.formErrors[field] = [];
fmArray.controls.forEach(g => this.formErrors[field].push(this.addressErrors));
let groupIndex = 0;
for (const groupItem of fmArray.controls) {
const group = <FormGroup>groupItem;
console.log("group index is here == " + groupIndex);
for (const ctrlField in this.addressErrors) {
const gpControl = group.controls[ctrlField];
this.formErrors[field][groupIndex][ctrlField] = '';
if (gpControl && gpControl.dirty && !gpControl.valid) {
const messages = this.validationMessages[ctrlField];
for (const key in gpControl.errors) {
console.log("control error key is here ==" + key);
this.formErrors[field][groupIndex][ctrlField] += messages[key] + ' ';
console.log("set value on object of key is here ==" + ctrlField)
console.log(this.formErrors[field][groupIndex]);
}
}
}
groupIndex++;
}
}
else {
this.formErrors[field] = '';
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
}
formErrors: any = {
'name': '',
'addresses': []
};
addressErrors: any = {
'street': ''
}
validationMessages: any = {
'name': {
'required': 'Name is required.',
'minlength': 'Name must be at least 4 characters long.'
},
'street': {
'required': 'Street is required.',
}
};
}
<h1>
Customer Dynamic Static Form Reactive</h1>
<form [formGroup]="customerForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" formControlName="name">
<div *ngIf="formErrors.name" class="alert alert-danger">
{{ formErrors.name }}
</div>
</div>
<!--addresses-->
<div formArrayName="addresses">
<div *ngFor="let address of customerForm.controls.addresses.controls; let i=index" class="panel panel-default">
<div class="panel-heading">
<span>Address {{i + 1}}</span>
<span class="glyphicon glyphicon-remove pull-right" *ngIf="customerForm.controls.addresses.controls.length > 1" (click)="removeAddress(i)"></span>
</div>
<div class="panel-body" [formGroupName]="i">
<address [group]="address"></address>
</div>
</div>
</div>
<div class="margin-20">
<a (click)="addAddress()" style="cursor: default"> Add another address +
</a>
</div>
<div class="margin-20">
<button type="submit" class="btn btn-primary pull-right" [disabled]="!customerForm.valid">Submit</button>
</div>
<div class="clearfix"></div>
<div class="margin-20">
<pre>formErrors: <br>{{formErrors | json}}</pre>
<div>myForm details:-</div>
<pre>Is myForm valid?: <br>{{customerForm.valid | json}}</pre>
<pre>form value: <br>{{customerForm.value | json}}</pre>
</div>
</form>
html 和 ts 文件
您是否尝试过采用 Angular 文档中概述的 onValueChanged
方法?
onValueChanged(data?: any) {
if (!this.heroForm) { return; }
const form = this.heroForm.form;
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[field] = '';
const control = form.get(field);
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
formErrors = {
'name': '',
'power': ''
};
我正在学习 angular 2.
中的反应式动态形式我想像 angular.io 食谱表单验证那样验证消息。
像这样:
this.heroForm.valueChanges
.subscribe(data => this.onValueChanged(data));
所以我订阅动态表单中的表单值更改
但是奇怪的事情发生了,比如:
我群里有两个地址,一个有效,两个无效。
所以错误信息应该是一个,但结果是两个!!
有人可以帮忙解决这个问题吗?
这里是run file
这是地址html和ts文件
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
moduleId: module.id,
selector: 'address',
templateUrl: 'address.component.html',
})
export class AddressComponent {
@Input('group')
public adressForm: FormGroup;
}
<div [formGroup]="adressForm">
<div class="form-group col-xs-6">
<label>street</label>
<input type="text" class="form-control" formControlName="street">
<small [hidden]="adressForm.controls.street.valid" class="text-danger">
Street is required
</small>
</div>
<div class="form-group col-xs-6">
<label>postcode</label>
<input type="text" class="form-control" formControlName="postcode">
</div>
</div>
这是应用
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormArray, FormBuilder, Validators } from '@angular/forms';
import { Customer } from '../model/customer.model';
@Component({
selector: 'customer-component',
templateUrl: 'customer.component.html',
})
export class CustomerComponent implements OnInit {
public customerForm: FormGroup;
constructor(private _fb: FormBuilder) { }
ngOnInit() {
this.customerForm = this._fb.group({
'name': ['', [Validators.required, Validators.minLength(5)]],
'addresses': this._fb.array([])
});
// add address
this.addAddress();
this.customerForm.valueChanges
.subscribe(data => this.onValueChanged(data));
this.onValueChanged(); // (re)set validation messages now
}
initAddress() {
return this._fb.group({
'street': ['', Validators.required],
'postcode': ['']
});
}
addAddress() {
const control = <FormArray>this.customerForm.controls['addresses'];
const addrCtrl = this.initAddress();
control.push(addrCtrl);
}
removeAddress(i: number) {
const control = <FormArray>this.customerForm.controls['addresses'];
control.removeAt(i);
}
onSubmit() {
}
onValueChanged(data?: any) {
const form = this.customerForm;
for (const field in this.formErrors) {
// clear previous error message (if any)
const control = form.get(field);
if (control instanceof FormArray) {
const fmArray = <FormArray>control;
console.log("from Array have count : " + fmArray.controls.length);
this.formErrors[field] = [];
fmArray.controls.forEach(g => this.formErrors[field].push(this.addressErrors));
let groupIndex = 0;
for (const groupItem of fmArray.controls) {
const group = <FormGroup>groupItem;
console.log("group index is here == " + groupIndex);
for (const ctrlField in this.addressErrors) {
const gpControl = group.controls[ctrlField];
this.formErrors[field][groupIndex][ctrlField] = '';
if (gpControl && gpControl.dirty && !gpControl.valid) {
const messages = this.validationMessages[ctrlField];
for (const key in gpControl.errors) {
console.log("control error key is here ==" + key);
this.formErrors[field][groupIndex][ctrlField] += messages[key] + ' ';
console.log("set value on object of key is here ==" + ctrlField)
console.log(this.formErrors[field][groupIndex]);
}
}
}
groupIndex++;
}
}
else {
this.formErrors[field] = '';
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
}
formErrors: any = {
'name': '',
'addresses': []
};
addressErrors: any = {
'street': ''
}
validationMessages: any = {
'name': {
'required': 'Name is required.',
'minlength': 'Name must be at least 4 characters long.'
},
'street': {
'required': 'Street is required.',
}
};
}
<h1>
Customer Dynamic Static Form Reactive</h1>
<form [formGroup]="customerForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" formControlName="name">
<div *ngIf="formErrors.name" class="alert alert-danger">
{{ formErrors.name }}
</div>
</div>
<!--addresses-->
<div formArrayName="addresses">
<div *ngFor="let address of customerForm.controls.addresses.controls; let i=index" class="panel panel-default">
<div class="panel-heading">
<span>Address {{i + 1}}</span>
<span class="glyphicon glyphicon-remove pull-right" *ngIf="customerForm.controls.addresses.controls.length > 1" (click)="removeAddress(i)"></span>
</div>
<div class="panel-body" [formGroupName]="i">
<address [group]="address"></address>
</div>
</div>
</div>
<div class="margin-20">
<a (click)="addAddress()" style="cursor: default"> Add another address +
</a>
</div>
<div class="margin-20">
<button type="submit" class="btn btn-primary pull-right" [disabled]="!customerForm.valid">Submit</button>
</div>
<div class="clearfix"></div>
<div class="margin-20">
<pre>formErrors: <br>{{formErrors | json}}</pre>
<div>myForm details:-</div>
<pre>Is myForm valid?: <br>{{customerForm.valid | json}}</pre>
<pre>form value: <br>{{customerForm.value | json}}</pre>
</div>
</form>
html 和 ts 文件
您是否尝试过采用 Angular 文档中概述的 onValueChanged
方法?
onValueChanged(data?: any) {
if (!this.heroForm) { return; }
const form = this.heroForm.form;
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[field] = '';
const control = form.get(field);
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
formErrors = {
'name': '',
'power': ''
};