表格形式。可以继承表单控件吗?

时间:2017-09-20 13:43:57

标签: forms angular typescript angular-forms

我有两个组件:ParentComponent和ChildComponent:

parent.component.ts

<form #form="ngForm" (ngSubmit)="onSubmit(form)" novalidate>
     <input type="text" name="firstControl" [(ngModel)]="firstControl" />
     <input type="text" name="secondControl" [(ngModel)]="secondControl" />
     <child-component>
</form>
{{form.value | json}}

child.component.ts

<input type="text" name="thirdControl" [(ngModel)]="thirdControl" />
<input type="text" name="fourthControl" [(ngModel)]="fourthControl" />

现在,{{form.value | json}}返回{ "firstControl": "", "secondControl": "" },很明显。我的问题是:有没有办法从子组件形成enherit表单控件?为ParentComponent获取{ "firstControl": "", "secondControl": "", "thirdControl": "", "fourthControl": "" }的正确方法是什么?可能吗?

2 个答案:

答案 0 :(得分:10)

<强>更新

确实有一种更简单的方法:

import { FormsModule, ControlContainer, NgForm, NgModel } from '@angular/forms';

@Component({
  ...
  viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
export class ChildComponent {}

另见

以前的版本:

我会说这是可能的。例如,您可以将以下代码添加到

<强> child.component.ts

import { NgForm, NgModel } from '@angular/forms';

@Component({
  selector: 'child-component',
  template: `
      <input type="text" name="thirdControl" [(ngModel)]="thirdControl" />
      <input type="text" name="fourthControl" [(ngModel)]="fourthControl" />
    `
})
export class ChildComponent {
  @ViewChildren(NgModel) ngModels: QueryList<NgModel>;

  constructor(@Optional() private ngForm: NgForm) {}

  ngAfterViewInit() {
    if (this.ngForm) {
      this.ngModels.forEach(model => this.ngForm.addControl(model));
    }
  }
}

<强> Plunker Example

Angular DI系统使我们有机会获得对父NgForm实例的引用,因为角度依赖性解析算法从当前节点开始并通过元素树向上。在我的例子中,我们可以想象下面的树

              @NgModule providers
                    |
                  my-app
                    |
                   form
          /         |       \
   input[text] input[text] child-component

因此,当我们要求NgForm时,令牌角度将按下一个顺序搜索

child-component
     ||
     \/
    form
     ||
     \/
   my-app
     ||
     \/
  @NgModule

在表单元素NgForm上放置指令,以便何时可以获取它。我们还可以获取NgForm数组中providers指令上声明的任何标记。此规则适用于任何节点。

另见Angular 2 - How does ng-bootstrap provide the NgbRadioGroup and NgbButtonLabel to their NgbRadio directive?

然后我只是手动将NgModel指令添加到NgForm,这样他们就可以一起工作。

答案 1 :(得分:0)

Angular有两种形式,模板驱动和反应。使用模板驱动表单无法实现您的目标,您需要查看Reactive Forms

通常,它通过在组件中创建表单对象并在模板中使用它来工作。 Angular说这实际上更灵活,更容易测试,但我认为语法更难以解决。

您希望在父组件中使用此功能:

  myForm: FormGroup; 

  constructor(private fb: FormBuilder) { // <--- inject FormBuilder
    this.createForm();
  }

  createForm() {
    this.myForm = this.fb.group({
      firstControl: '',
      secondControl: '',
      thirdControl: '',
      fourthControl: ''
    });
  }

您的父模板如下所示:

<form [formGroup]="myForm" novalidate>
<input type="text"formControlName="firstControl" />
     <input type="text" formControlName="secondControl" />
     <child-component [parentFormGroup]="myForm">
</form>

您的孩子将接受表单组作为输入,模板将如下所示:

<div class="form-group" [formGroup]="parentFormGroup">
  <input type="text" formControlName="thirdControl" />
  <input type="text" formControlName="fourthControl" />
</div>