【问题标题】:Angular 2 Form validation for dynamic fields动态字段的Angular 2表单验证
【发布时间】:2017-09-26 01:11:53
【问题描述】:

我正在开发一个 Angular 4.X 项目,并在单击按钮时创建一些 HTML 输入字段(主要是文本类型)。动态创建输入框工作正常,但我无法对这些字段进行验证。我收到以下错误。

无法读取 null(...) 的属性“无效”

我已经为此创建了一个 plunk。以下是我创建的 plunk 的链接--

https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview 为了方便参考,请在下面找到代码--

//Root app component
import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { FormBuilder, FormGroup, Validators, FormArray, FormControl } from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@Component({
  selector: 'my-app',
  template: `<hr>
              <div>  
                <form [formGroup]="orderForm" (ngSubmit)="OnSubmit(orderForm.value)">
                  <div>
                    <input type="text" formControlName="customerName"/>
                    <input type="text" formControlName="email"/>
                  </div>
                  <div formArrayName="items" *ngFor="let item of items.controls; let i = index;">
                    <div [formGroupName]="i">
                      <input type="text" formControlName="name" placeholder="Item name"/>
                      <small *ngIf="IsValidField('name')" class="text-danger">
                        Name is required
                      </small>
                      <input type="text" formControlName="description" placeholder="Item description"/>
                      <small *ngIf="IsValidField('description')" class="text-danger">
                        Description is required
                      </small>
                      <input type="text" formControlName="price" placeholder="Item price"/>
                      <small *ngIf="IsValidField('price')" class="text-danger">
                        Price is required
                      </small>
                    </div>
                    Chosen name: {{ orderForm.controls.items.controls[i].controls.name.value }}
                  </div>
                  <button type="submit">Save</button>
                  <button type="button" (click)="addItem()">Add More</button>
                </form>
              <div>`,
})

export class App {

  constructor(private formBuilder: FormBuilder) {  }

  public orderForm: FormGroup;



  ngOnInit() {
      this.orderForm = this.formBuilder.group({
        customerName: '',
        email: '',
        items: this.formBuilder.array([ this.createItem()])
      });
  }

 createItem(): FormGroup {
    return this.formBuilder.group({
      name: ['',[Validators.required,Validators.maxLength(10)]],
      description: '',
      price: ['',[Validators.required,Validators.pattern("[(0-9)*]")]]
    });
  }

   get items(): FormArray {
    return this.orderForm.get('items') as FormArray;
   };

  addItem(): void {
  this.items.push(this.createItem());
  }

  public OnSubmit(formValue: any) {
        console.log(JSON.stringify(formValue));
    }

    public IsValidField(field: string) {
        return (this.orderForm.get(field).invalid && this.orderForm.get(field).touched) || (this.orderForm.get(field).invalid && this.orderForm);
    }

}

@NgModule({
  imports: [ BrowserModule, FormsModule, ReactiveFormsModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

任何帮助将不胜感激。

【问题讨论】:

    标签: angular angular2-forms


    【解决方案1】:

    您正在orderForm 中搜索动态添加的表单字段,该字段在该处不可用。您应该在访问其值之前正确查询表单。我绘制了下图,这将帮助您了解动态创建的表单架构。

    orderForm (FormGroup)
      |
      - Items (FormArray)
        |
         - 0 (FormGroup)
           - name 
           - description
           - price
        |
         - 1 (FormGroup)
           - name
           - description
           - price
        |
        |.........
    

    所以IsValidField 函数应该获得formArray 元素的index 和字段名称。通过它您可以轻松查询表单元素。

    public IsValidField(i: number, field: any) {
        var f = this.orderForm
                .get('items') //retrieve items FormArray
                .get(i.toString()) //retrieve items FormGroup
                .get(field); //retrieve items form field
        return (f.invalid && f.touched) || (f.invalid && this.orderForm);
    }
    

    然后相应地更改*ngIf 上的IsValidField 函数调用。

    *ngIf="IsValidField(i, 'name')"
    *ngIf="IsValidField(i, 'description')"
    *ngIf="IsValidField(i, 'price')"
    

    Demo Plunker

    【讨论】:

    • 感谢 Pankaj,它真的很有帮助。你能告诉我如何用数据填充这些字段,我正在尝试这样做,但它不起作用。这是 link 的 Plunker
    • @AmitAnand 使用.patchValue 填充值
    • 但是我将如何为多个字段做这件事,而且太动态了。您能否调查一下 Plunker 并为我提供解决方案。
    • @AmitAnand 我请求你打开新问题,以便其他人也可以加入。
    • 我创建了一个。请在这里找到它link提前谢谢
    猜你喜欢
    • 1970-01-01
    • 2018-05-27
    • 2017-06-17
    • 2014-02-22
    • 2016-08-21
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 2020-11-27
    相关资源
    最近更新 更多