首页 文章

FormArray,带有Angular 5的Reactive Form中的嵌套控件组

提问于
浏览
0

我一直在尝试使用反应方法在Angular中创建一个表单 . 所有似乎都没问题,直到我需要使用FormArray与嵌套的FormGroup . 我们的想法是获得一个看起来像下面的对象的输出,并能够将尽可能多的项目传递给items数组 .

{ 
  'companyName': '',
  'nifcif': '',
  'postcode': '',
  'invoiceNo': 0,
  'invoiceDate': 00/00/00,
  'items': [{'itemQty' : 0, 'itemName' : 0, 'itemPrice' : 0}]
 }

所以基本上所有表格都可以正常工作,除非是项目部分 . 我得到这个错误mesaje

Cannot find control with name: 'itemQty'

我必须以某种方式使每个项目的控件名称与数组中的索引相连(我猜)但我尝试了不同的方法但没有成功 . 你能建议吗?提前致谢!!


这是我的TS文件(我没有打扰创建一个方法将更多项传递给数组):

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, FormArray } from '@angular/forms';

@Component({
  selector: 'app-process-invoice',
  templateUrl: './process-invoice.component.html',
  styleUrls: ['./process-invoice.component.css']
})
export class ProcessInvoiceComponent implements OnInit {

  invoiceForm: FormGroup;

  constructor() {}


  ngOnInit() {
    let items = new FormArray([new FormGroup({ 'itemQty': new FormControl(null), 'itemName': new FormControl(null)})])
    this.invoiceForm = new FormGroup({
      'companyName': new FormControl(null),
      'nifcif': new FormControl(null),
      'postcode': new FormControl(null),
      'invoiceNo': new FormControl(null),
      'invoiceDate': new FormControl(null),
      'items': items
    })



  }

  onSubmit() {
    console.log(this.invoiceForm);
  }

}

在这里我的HTML:

<form [formGroup]="invoiceForm"> 
  <div class="container">
    <div class="row">
      <div class="col-md-6">
        <h3>Company Name:</h3><input formControlName="companyName" type="text" class="form-control form-control-sm" required/>
        <p>NIF/CIF:</p><input formControlName="nifcif" type="text" class="form-control form-control-sm" required/>
        <p>Postal Code:</p><input formControlName="postcode" type="text" class="form-control form-control-sm"/>
      </div>
      <div class="col-md-6">
        <p>Invoice No.:</p><input formControlName="invoiceNo" type="number" class="form-control form-control-sm" required/>
        <p>Date:</p><input formControlName="invoiceDate" type="date" class="form-control form-control-sm" required/>
      </div>
    </div>
  </div>
  <div class="container">
    <div class="table-responsive">
      <table class="table table-sm">
        <thead>
          <tr>
            <th>Qty.</th>
            <th>Product</th>
            <th>Price</th>
            <th></th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><input formControlName="itemQty" type="number" class="form-control form-control-sm" required/></td>
            <td><input FormControlName="itemName" type="text" class="form-control form-control-sm" required/></td>
            <td><input formControlName="itemPrice" type="number" class="form-control form-control-sm" required/></td>
            <td><button class="btn btn-outline-primary">+</button></td>
            <td><button class="btn btn-outline-danger">-</button></td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
  <div class="container border">
    <div class="row">
      <div class="col-3"><p>SubTotal : £</p><span></span></div>
      <div class="col-3">
        <div class="input-group">
          <div class="input-group-prepend">VAT %</div>
          <input type="number" class="form-control form-control" id="vat" name="vat" />
        </div>
      </div>
      <div class="col-3"><p>Rebate</p></div>
      <div class="col-3"><p>Total</p></div>
    </div>
  </div>
  <div class="container">
    <div class="row">
      <div class="col"><button (click)="onSubmit()" type="submit" class="btn btn-success">Submit</button></div>
      <div class="col"><button (click)="onDiscardInvoice()" class="btn btn-danger">Discard</button></div>
    </div>
  </div>
</form>

2 回答

  • 1

    我有类似的东西...但我允许使用FormGroup定义多个地址 .

    我的代码如下所示:

    Component

    ngOnInit(): void {
        this.customerForm = this.fb.group({
            firstName: ['', [Validators.required, Validators.minLength(3)]],
            lastName: ['', [Validators.required, Validators.maxLength(50)]],
            emailGroup: this.fb.group({
                email: ['', [Validators.required, Validators.pattern('[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+')]],
                confirmEmail: ['', Validators.required],
            }, {validator: emailMatcher}),
            phone: '',
            notification: 'email',
            rating: ['', ratingRange(1, 5)],
            sendCatalog: true,
            addresses: this.fb.array([this.buildAddress()])
        });
    }
    
    addAddress(): void {
        this.addresses.push(this.buildAddress());
    }
    
    buildAddress(): FormGroup {
        return this.fb.group({
                addressType: 'home',
                street1: '',
                street2: '',
                city: '',
                state: '',
                zip: ''
        });
    }
    

    Template

    <div formArrayName="addresses" *ngFor="let address of addresses.controls; let i=index">
                        <div [formGroupName]="i">
                            <div class="form-group" >
                                <label class="col-md-2 control-label"
                                       attr.for="{{'addressType1Id' + i}}">Address Type</label>
                                <div class="col-md-8">
                                    <label class="radio-inline">
                                        <input type="radio" id="{{'addressType1Id' + i}}" value="home"
                                        formControlName="addressType">Home
                                    </label>
                                    <label class="radio-inline">
                                        <input type="radio" id="{{'addressType1Id' + i}}" value="work"
                                        formControlName="addressType">Work
                                    </label>
                                    <label class="radio-inline">
                                        <input type="radio" id="{{'addressType1Id' + i}}" value="other"
                                        formControlName="addressType">Other
                                    </label>
                                </div>
                            </div>
    
                            <div class="form-group">
                                <label class="col-md-2 control-label"
                                       attr.for="{{'street1Id' + i}}">Street Address 1</label>
                                <div class="col-md-8">
                                    <input type="text" 
                                        class="form-control" 
                                        id="{{'street1Id' + i}}" 
                                        placeholder="Street address"
                                        formControlName="street1">
                                </div>
                            </div>
                      ...
    

    请注意我是如何使用: id="{{'street1Id' + i}}" 生成唯一ID的 .

    另请注意HTML的前两行,它们定义了 formArrayName 指令和 formGroupName 指令 .

    您可以在我的github中找到完整的代码:https://github.com/DeborahK/Angular2-ReactiveForms在Demo-Final文件夹中 .

  • 0

    排序,我试图以错误的方式做* ngFor .

    我只需要包括 *ngFor="let item in invoiceform.controls.items.controls; let i = index" [formGroupName] = "i"

    我的错误是试图通过 items.controls 直接遍历formArray(整个表格形式)

相关问题