繁体   English   中英

Angular 2反应形式的嵌套数组?

[英]Nested arrays in Angular 2 reactive forms?

我使用以下教程在Angular 2中创建反应形式,它运行良好。

https://scotch.io/tutorials/how-to-build-nested-model-driven-forms-in-angular-2

但是,我现在正在尝试在数组中添加一个数组。 使用上面的教程,我创建了一个“组织”表单,其中可以包含一组“联系人”组。 但我无法成功调整设置以允许每个“联系人”组包含一组“电子邮件”组。

我一直无法找到涵盖此内容的教程或示例,并对任何指针表示感谢。

使用上面的教程,我创建了一个“组织”表单,其中可以包含一组“联系人”组。 但我无法成功调整设置以允许每个“联系人”组包含一组“电子邮件”组。

上面的教程为您提供了所需的一切。

我想你想要这样的结构。

在此输入图像描述

首先,你需要一些组件( AppComponent ,你声明的根在我的情况) FormGroup 我在下面称它为trustForm

app.component.ts

export class AppComponent {
  trustForm: FormGroup;

  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.trustForm = this.fb.group({
      name: '',
      contracts: this.fb.array([])
    });

    this.addContract();
  }

  initContract() {
    return this.fb.group({
      name: '',
      emails: this.fb.array([])
    });
  }

  addContract() {
    const contractArray = <FormArray>this.trustForm.controls['contracts'];
    const newContract = this.initContract();

    contractArray.push(newContract);
  }

  removeContract(idx: number) {
    const contractsArray = <FormArray>this.trustForm.controls['contracts'];
    contractsArray.removeAt(idx);
  }
}

在这个组件中,您还有一些方法可以帮助您操作第一级FormArray - contracts

app.component.html

<div class="container">
    <form [formGroup]="trustForm">
        <h3>Add trust</h3>

        <div class="form-group">
            <label>Name</label>
            <input type="text" class="form-control" formControlName="name">
        </div>

        <!--contracts-->
        <div formArrayName="contracts">
            <div *ngFor="let contract of trustForm.controls.contracts.controls; let i=index" class="panel panel-default">
                <div class="panel-heading">
                    <span>Contract {{i + 1}}</span>
                    <span class="glyphicon glyphicon-remove pull-right" *ngIf="trustForm.controls.contracts.controls.length > 1" (click)="removeContract(i)"></span>
                </div>
                <div class="panel-body" [formGroupName]="i">
                    <contract [group]="trustForm.controls.contracts.controls[i]"></contract>
                </div>
            </div>
        </div>
        <div class="margin-20">
            <button (click)="addContract()" class="btn btn-primary">
                Add another contract +
            </button>
        </div>

    </form>

    <h5>Details</h5>
    <pre>{{ trustForm.value | json }}</pre>
</div>

除了不同的FormArray名称之外,与教程中的root html没有什么不同。

然后,您需要构建与AppComponent类似的合约组件

contract.component.ts

export class ContractComponent {
    @Input('group') contractGroup: FormGroup;

    constructor(private fb: FormBuilder) { }

    addEmail() {
        const emailArray = <FormArray>this.contractGroup.controls['emails'];
        const newEmail = this.initEmail();

        emailArray.push(newEmail);
    }

    removeEmail(idx: number) {
        const emailArray = <FormArray>this.contractGroup.controls['emails'];
        emailArray.removeAt(idx);
    }

    initEmail() {
        return this.fb.group({
            text: ''
        });
    }
}

contract.component.html

<div [formGroup]="contractGroup">
    <div class="form-group">
        <label>Name</label>
        <input type="text" class="form-control" formControlName="name">
    </div>

    <!--emails-->
    <div formArrayName="emails">
        <div *ngFor="let email of contractGroup.controls.emails.controls; let i=index" class="panel panel-default">
            <div class="panel-heading">
                <span>Email {{i + 1}}</span>
                <span class="glyphicon glyphicon-remove pull-right" *ngIf="contractGroup.controls.emails.controls.length > 1" (click)="removeEmail(i)"></span>
            </div>
            <div class="panel-body" [formGroupName]="i">
                <email [group]="contractGroup.controls.emails.controls[i]"></email>
            </div>
        </div>
    </div>
    <div class="margin-20">
        <button (click)="addEmail()" class="btn btn-primary">
            Add another email +
        </button>
    </div>

</div>

正如您所看到的,我们只是将contracts替换为emails FormArray ,我们也将FormGroup传递给电子邮件组件

最后,您只需要使用所需字段填充EmailComponent

email.component.ts

export class EmailComponent {
    @Input('group') emailGroup: FormGroup;
}

email.component.html

<div [formGroup]="emailGroup">
    <div class="form-group">
        <label>Text</label>
        <input type="text" class="form-control" formControlName="text">
    </div>
</div>

您可以在Plunker Example中找到完成的版本

如果你认为这个解决方案似乎并不正确,因为父组件拥有像子组件的描述initContractinitEmails你可以在更复杂的看看

Plunker示例

每个组件负责其功能。

如果您正在寻找模板驱动表单的解决方案,请阅读以下文章:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM