如何显示动态表单数组的md-error消息?

时间:2017-07-11 12:25:53

标签: angular typescript angular2-forms

我有一个动态表单数组,如果我单击添加联系人按钮,它将添加动态表单字段后,我尝试验证表单字段(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)
    }


}

2 个答案:

答案 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')"