具有子组件和验证的Angular 2嵌套表单

时间:2017-06-07 09:05:07

标签: forms angular validation components

我尝试使用Angular 2中的验证来实现嵌套表单,我已经看过帖子并按照文档进行操作,但我真的很挣扎,希望你能指出我正确的方向。< / p>

我想要实现的是拥有一个带有多个子组件的经过验证的表单。这些子组件有点复杂,其中一些有更多的子组件,但为了这个问题,我认为我们可以解决有父母和孩子的问题。

我想要完成的是什么

有一个像这样的表单:

<div [formGroup]="userForm" novalidate>
    <div>
        <label>User Id</label>
        <input formControlName="userId">
    </div>
    <div>
        <label>Dummy</label>
        <input formControlName="dummyInput">
    </div>
</div>

这需要这样的课程:

private userForm: FormGroup;
constructor(private fb: FormBuilder){
    this.createForm();
}
private createForm(): void{
    this.userForm = this.fb.group({
        userId: ["", Validators.required],
        dummyInput: "", Validators.required]
    });
}

这可以按预期工作,但现在我想要解耦代码,并将&#34; dummyInput&#34;功能在一个单独的不同组件中。这是我迷路的地方。这就是我尝试过的,我想我距离得到答案不远,但我真的没有想法,我对这个场景很新:

parent.component.html

<div [formGroup]="userForm" novalidate>
    <div>
        <label>User Id</label>
        <input formControlName="userId">
    </div>
    <div>
        <dummy></dummy>
    </div>
</div>

parent.component.ts

private createForm(): void{
    this.userForm = this.fb.group({
    userId: ["", Validators.required],
    dummy: this.fb.group({
        dummyInput: ["", Validators.required]
    })
});

children.component.html

<div [formGroup]="dummyGroup">
    <label>Dummy Input: </label>
    <input formControlName="dummyInput">
</div>

children.component.ts

private dummyGroup: FormGroup;

我知道代码有些不对劲,但我真的遇到了问题。任何帮助都会受到重视。

感谢。

5 个答案:

答案 0 :(得分:10)

您可以在子组件中添加一个Input以将FormGroup传递给它。并使用​​FormGroupName传递FormGroup的名称:)

<强> children.component.ts

@Input('group');
private dummyGroup: FormGroup;

<强> parent.component.html

<div [formGroup]="userForm" novalidate>
    <div>
        <label>User Id</label>
        <input formControlName="userId">
    </div>
    <div formGroupName="dummy">
        <dummy [group]="userForm.controls['dummy']"></dummy>
    </div>
</div>

答案 1 :(得分:3)

不会撒谎,不知道我之前怎么没找到这篇文章。

Angular 2: Form containing child component

解决方案是将children组件绑定到同一个formGroup,方法是将formGroup从父组件传递给子组件作为输入。

如果有人分享一段代码以其他方式解决问题,我很乐意接受。

答案 2 :(得分:1)

要获取对父表单的引用,只需使用它(在Angular 2中可能不可用。我已经在Angular 6中对其进行了测试):

TS

import {
   FormGroup,
   ControlContainer,
   FormGroupDirective,
} from "@angular/forms";

@Component({
  selector: "app-leveltwo",
  templateUrl: "./leveltwo.component.html",
  styleUrls: ["./leveltwo.component.sass"],
  viewProviders: [
    {
      provide: ControlContainer,
      useExisting: FormGroupDirective
    }
  ]
})
export class NestedLevelComponent implements OnInit {
  //form: FormGroup;

  constructor(private parent: FormGroupDirective) {
     //this.form = form;
  }
}

HTML

<input type="text" formControlName="test" />

答案 3 :(得分:0)

import { Directive } from '@angular/core';
import { ControlContainer, NgForm } from '../../../node_modules/@angular/forms';

@Directive({
  selector: '[ParentProvider]',
  providers: [
    {
    provide: ControlContainer,
    useFactory: function (form: NgForm) {
      return form;
    },
    deps: [NgForm]
    }`enter code here`
  ]
})
export class ParentProviderDirective {

  constructor() { }

}
<div ParentProvider >
  for child
</div>

答案 4 :(得分:0)

FormGroupDirective(如@blacksheep's answer中所述)的替代方法是使用ControlContainer,如下所示:

import { FormGroup, ControlContainer } from "@angular/forms";

export class ChildComponent implements OnInit {

  formGroup: FormGroup;

  constructor(private controlContainer: ControlContainer) {}

  ngOnInit() {
    this.formGroup = <FormGroup>this.controlContainer.control;
  }

formGroup可以设置在直接父级或更高级别(例如,父级的父级)中。这样就可以在不同的嵌套组件之间传递from组,而无需@Input()链来传递formGroup。在任何父级中,将formGroup设置为可通过ControlContainer在子级中使用:

<... [formGroup]="myFormGroup">