问:如何使用带有ng-content的Angular 2模板表单?

Son*_*reB 21 angular2-forms angular

是否不可能在ng-content中包含表单输入元素并将其"连接"到父组件的ngForm实例?

将此基本模板用于父组件:

<form (ngSubmit)="onSubmit(editForm)" #editForm="ngForm" novalidate>               
<ng-content></ng-content>
<button type="submit">Submit</button>
</form>
Run Code Online (Sandbox Code Playgroud)

然后在子组件里面放入"ng-content",如下所示:

<input type="text" [(ngModel)]="user.firstName" #firstName="ngModel" name="firstName" required minlength="2">
Run Code Online (Sandbox Code Playgroud)

在提交父表单时,子控件不可用,这也意味着子组件中的任何内容的脏/验证不会反映在父表单上.

这里缺少什么?

ins*_*hex 23

你现在很有可能想出另一个解决方案,但我只想出办法来做到这一点.希望它能帮助你或其他人.

import { NgModel } from '@angular/forms';
import { Component, ContentChildren, ViewChild, QueryList, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-custom-form',
  template: `
    <form (ngSubmit)="onSubmit(editForm)" #editForm="ngForm" novalidate>               
      <ng-content></ng-content>
      <button type="submit">Submit</button>
    </form>
  `,
})
export class MyCustomFormComponent implements AfterViewInit {
  @ContentChildren(NgModel) public models: QueryList<NgModel>;
  @ViewChild(NgForm) public form: NgForm;

  public ngAfterViewInit(): void {
    let ngContentModels = this.models.toArray();
    ngContentModels.forEach((model) => {
      this.form.addControl(model);
    });
  }

  public onSubmit(editForm: any): void {
    console.log(editForm);
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以在你的模板中使用它,如下所示:

<my-custom-form>
  <input name="projectedInput" ngModel>
</my-custom-form>
Run Code Online (Sandbox Code Playgroud)

提交表单时,您将看到projectionInput表单控件已添加到NgForm中.

注意:我只尝试从AfterViewInit生命周期钩子添加投影输入.它可能更早,我不确定.这样做可能还有一些我不知道的问题.因人而异.

  • 如果您也将 `{descendants: true}` 指定给 `ContentChildren`,那么它也会抓取后代,并且您不需要将输入作为直接子项 :) (2认同)