angular - 将组件动态添加到表单中的 FormArray( Angular 2/4)

标签 angular

我有一个注册表单,用户可以在其中向新的或现有的组织添加一个/多个地址、一个/多个电话,地址和电话实际上是(可重用的)组件。

例如,Phone 组件与 Android 联系人详细信息组件类似,它有 3 个 FormControls:一个 Type(下拉列表)、一个数字(输入)和一个删除按钮。

最后,必须提交整个表单以保存信息。

问题:如何动态添加电话到表单并显示已经存在的电话? (下面的代码和标记)。非常感谢您花时间和精力回答我!

organization-detail.component.ts

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

import { Organization } from './organization';
import { PhoneDetailComponent } from "../phone-detail/phone-detail.component";

@Component({
    selector: 'organization-detail',
    templateUrl: './organization-detail.component.html',
    styleUrls: ['./organization-detail.component.css']
})

export class OrganizationDetailComponent {
    organizationForm: FormGroup;

    constructor (private fb: FormBuilder){
      this.createForm();
    }

    createForm() {
        this.organizationForm = this.fb.group({
        accountingId: [''],
        externalId: '',
        isHost: false,
        logoPath: '',
        name: ['', 
            [Validators.required,
            Validators.minLength(4),
            Validators.maxLength(24)]
            ], // <--- the FormControl called "name"
        notes: '',
        registrationNo: '',
        vATId: '',
        webSite: '',
        phones: new FormArray([])
        //phones: new Array<PhoneDetailComponent>
        });
    }

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

    onAddPhone() {
      const control = new PhoneDetailComponent();
      (<FormArray>this.organizationForm.get('phones')).push(control);
    }

}

organization-detail.component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <h2>Organization Detail</h2>
      <form [formGroup]="organizationForm" (ngSubmit)="onSubmit()" class="form-horizontal">
        <div class="form-group">
          <label for="isHost"> Is host:</label>
          <input type="checkbox" id="isHost" formControlName="isHost" class="check" />
        </div>
        <div class="form-group">
          <label for="name">Name:</label>
          <input type="text" id="name" class="form-control" formControlName="name" placeholder="Organization name" />
          <span 
            *ngIf="!organizationForm.get('name').valid && organizationForm.get('name').touched" 
            class="help-block">Please enter a valid name!</span>
        </div>
        <div class="form-group">
          <label for="accountingId">Accounting Id:</label>
          <input type="text" id="accountingId" class="form-control" formControlName="accountingId" />
        </div>
        <div class="form-group">
          <label for="externalId">External Id:</label>
          <input type="text" id="externalId" class="form-control" formControlName="externalId" />
        </div>
        <div class="form-group">
          <label for="registrationNo">Registration No:</label>
          <input type="text" id="registrationNo" class="form-control" formControlName="registrationNo" />
        </div>
        <div class="form-group">
          <label for="vATId">VAT Id:</label>
          <input type="text" id="vATId" class="form-control" formControlName="vATId" />
        </div>
        <div class="form-group">
          <label for="webSite">Web site:</label>
          <input type="text" id="webSite" class="form-control" formControlName="webSite" />
        </div>
        <div class="form-group">
          <label for="logoPath">Logo path:</label>
          <input type="text" id="logoPath" class="form-control" formControlName="logoPath" />
        </div>
        <div class="form-group">
          <label for="notes">Notes:</label>
          <textarea id="notes" class="form-control" formControlName="notes" rows="3"></textarea>
        </div>
        <div formArrayName="phones">
          <h4>Phones:</h4>
          <button class="btn btn-default" type="button"
            (click)="onAddPhone()">
            Add phone
          </button>
          <div class="form-group"
            *ngFor="let phoneControl of organizationForm.get('phones').controls; let i = index">
            <!--<input type="text" class="form-control" [formControlName]="i">-->
            <phone-detail></phone-detail>
          </div>
        </div>
        <div class="form-group">
          <div class="input-group">
            <input type="text" class="form-control">
            <span class="input-group-btn">
                  <button class="btn btn-default" type="button">Go!</button>
            </span>
          </div>
        </div>
        <button class="btn btn-primary" type="submit">Submit</button>
      </form>
    </div>
  </div>
</div>
<p>Form value: {{ organizationForm.value | json }}</p>
<p>Form status: {{ organizationForm.status | json }}</p>

phone-detail.component.ts

import { Component, OnInit, Input } from '@angular/core';

import { Phone } from "./phone";

@Component({
  selector: 'phone-detail',
  templateUrl: './phone-detail.component.html',
  styleUrls: ['./phone-detail.component.css']
})
export class PhoneDetailComponent implements OnInit {
  @Input('phoneItem') item: Phone;

  constructor() { }

  ngOnInit() {
  }
}

phone-detail.component.html

<div class="container">
  <div class="row">
    <div class="col-xs-3">
      <select class="form-control">
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
        <option>5</option>
      </select> 
    </div>
    <div class="col-xs-7">
      <input type="text" class="form-control">
    </div>
    <div class="col-xs-2">
      <button class="btn">X</button>
    </div>
  </div>
</div>

最佳答案

在你的父级中,有格式数组:

phones: this.fb.array([])

然后在父模板中将这个 formarray 中的每个表单组传递给子模板:

<button (click)="addPhone()">Add phone</button>
<div formArrayName="phones">
  <div *ngFor="let ctrl of organizationForm.controls.phones.controls; let i=index">
    <button (click)="removePhone(i)">X</button>
    <phone-detail [group]="ctrl"></phone-detail>
  </div>
</div>

在 child 中使用@Input:

@Input() group: FormGroup;

并在模板中添加表单控件和表单组:

<div [formGroup]="group">
  <select formControlName="type">
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
    <option>5</option>
  </select> 
  <input type="text" formControlName="num">
</div>

最后是删除和添加放置在父级中的表单组:

initPhone() {
  return this.fb.group({
    type: [''],
    num: ['']
  });
}

addPhone() {
    const control = this.organizationForm.controls.phones;
    control.push(this.initPhone());
}

removePhone(i: number) {
    const control = this.organizationForm.controls.phones;
    control.removeAt(i);
}

This article 关于这个问题值得一读!

关于angular - 将组件动态添加到表单中的 FormArray( Angular 2/4),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44471532/

相关文章:

Angular Cli-在 StyleURL 中添加位于 node_module 目录中的 css 文件

Angular2,如何清除路由器导航上的 URL 查询参数

angular - typescript : Can't instantiate object using object literals when a function exists in the class

angular - 使用 'Bootstrap'主题

angular - 如何创建可以支持ngModel和ngControl指令的组件

angular - 如何压缩和优化 Angular2 应用程序

javascript - Angular 2根据用户输入重新加载当前组件

typescript - 什么是 typescript 类型?

angular - 无法使用 IE 11 和 Angular 4 在 ArcgisMap 上拖动

angular - 未捕获的无效提供者 - 仅允许提供者和类型的实例,得到 : [object Object]