Forms Angular 2:从多个组件组成表单的惯用方法

Forms Angular 2:从多个组件组成表单的惯用方法,forms,angular,Forms,Angular,为了学习Angular 2,我正在制作一个饮食跟踪器,以配合我和妻子正在尝试的最新时尚饮食。这本书有几个问题可以用按钮回答(你饿了多少,非常饿,等等),外加一个可选的文本输入。还有基于复选框的问题,以及日期 我试图创建一个由多个组件组成的表单,一个用于按钮问题,一个用于复选框问题。看这个 我所好奇的是,如何将每个具有自己的表单元素的组件组成日常表单。每个子组件都有表单元素,还使用*ngFor循环外部文件中的数据(question data.ts)。目前,每个组件都有一个每日表单订阅的事件发射器

为了学习Angular 2,我正在制作一个饮食跟踪器,以配合我和妻子正在尝试的最新时尚饮食。这本书有几个问题可以用按钮回答(你饿了多少,非常饿,等等),外加一个可选的文本输入。还有基于复选框的问题,以及日期

我试图创建一个由多个组件组成的表单,一个用于按钮问题,一个用于复选框问题。看这个

我所好奇的是,如何将每个具有自己的表单元素的组件组成日常表单。每个子组件都有表单元素,还使用
*ngFor
循环外部文件中的数据(
question data.ts
)。目前,每个组件都有一个每日表单订阅的事件发射器

这是每日表单模板(
src/Daily.component.ts
):

dataEntered()
方法执行此操作(单击任何按钮也会调用此方法):

然后,
Daily
组件订阅其子组件上的事件发射器,并将处理最终验证/数据库接口(我仍在努力学习这一部分)

但我觉得在子组件上使用原始事件侦听器是错误的方法:例如,我不知道如何将子组件上的验证器连接到表单整体上的验证。我也不认为我完全使用了内置的Angular 2功能。据我所知,我觉得这并没有遵循松耦合原理

我倾向于以某种方式将子组件收集到
每日
组件中的主
控制组
,但我不确定如何做到这一点


谢谢

我不知道这种方法是否可取,但这是一种方法。子组件可以使用
@angular/forms
中的
ControlContainer
来访问其父控件的
FormGroup

父组件类型脚本文件:

// imports go here

@Component({
  selector: "app-parent",
  templateUrl: "./parent.component.html",
  styleUrls: ["./parent.component.css"]
})
export class ParentComponent implements OnInit {
    // Just create a typical FormGroup.
    fg: FormGroup;

    // Instantiate the FormGroup using your preferred method.
    constructor(fb: FormBuilder) {
        this.fg = this.fb.group({ FirstName: "John", LastName: "Doe" });
    }
}
import { Component } from "@angular/core";
import { ControlContainer } from "@angular/forms";

@Component({
  selector: "app-child",
  templateUrl: "./child.component.html",
  styleUrls: ["./child.component.css"]
})
export class ChildComponent {
  // Ask the framework for a ControlContainer whose control property has the goods.
  constructor(public controlContainer: ControlContainer) { }

  ngOnInit(): void {
  }
}
父组件模板文件:

<!-- Bind a form in the parent component to your FormGroup. -->
<form [formGroup]="fg">
    <!-- Reference the child component.  No need for @Inputs or fancy bindings. -->
    <app-child></app-child>
</form>
<!-- Finally, bind some top-level element to the imported FormGroup. -->
<fieldset [formGroup]="controlContainer.control">
    <legend>Reusable Controls Go Here</legend>

    <div>
        First Name
        <!-- Now, use the FormGroup per normal. -->
        <input formControlName="FirstName" type="text" />
    </div>
    <div>
        Last Name
        <input formControlName="LastName" type="text" />
    </div>
    <div>
        Accessing the FormGroup
        <!-- You can even get fancy. -->
        {{ controlContainer.control.get('FirstName')?.errors | json }}
    </div>
</fieldset>
子组件模板文件:

<!-- Bind a form in the parent component to your FormGroup. -->
<form [formGroup]="fg">
    <!-- Reference the child component.  No need for @Inputs or fancy bindings. -->
    <app-child></app-child>
</form>
<!-- Finally, bind some top-level element to the imported FormGroup. -->
<fieldset [formGroup]="controlContainer.control">
    <legend>Reusable Controls Go Here</legend>

    <div>
        First Name
        <!-- Now, use the FormGroup per normal. -->
        <input formControlName="FirstName" type="text" />
    </div>
    <div>
        Last Name
        <input formControlName="LastName" type="text" />
    </div>
    <div>
        Accessing the FormGroup
        <!-- You can even get fancy. -->
        {{ controlContainer.control.get('FirstName')?.errors | json }}
    </div>
</fieldset>

可重用控件位于此处
名字
姓
访问FormGroup
{{controlContainer.control.get('FirstName')?.errors | json}
<!-- Finally, bind some top-level element to the imported FormGroup. -->
<fieldset [formGroup]="controlContainer.control">
    <legend>Reusable Controls Go Here</legend>

    <div>
        First Name
        <!-- Now, use the FormGroup per normal. -->
        <input formControlName="FirstName" type="text" />
    </div>
    <div>
        Last Name
        <input formControlName="LastName" type="text" />
    </div>
    <div>
        Accessing the FormGroup
        <!-- You can even get fancy. -->
        {{ controlContainer.control.get('FirstName')?.errors | json }}
    </div>
</fieldset>