【问题标题】:Angular (4): transfer ngForm & ngModelGroup from parent to child and use form validationAngular(4):将 ngForm & ngModelGroup 从父级转移到子级并使用表单验证
【发布时间】:2018-03-28 08:32:35
【问题描述】:

我想将我的 ngForm 和 ngModelGroup 从父组件转移到子组件,并在子组件中使用表单验证功能。

父组件.html:

<md-step [stepControl]="createIntegrationPartnerRequestGroup">
  <form #createIntegrationPartnerRequestForm="ngForm">
    <div ngModelGroup="createIntegrationPartnerRequestGroup" #createIntegrationPartnerRequestGroup="ngModelGroup">
      <div class="row p-row-padding">
        <div class="col-xs-12">
          <ng-template mdStepLabel>
            {{'INTEGRATION_PARTNER_REQUEST' | translate}}
          </ng-template>
        </div>
      </div>
      <integration-partner-request [form]="createIntegrationPartnerRequestForm"
                                   [model]="createIntegrationPartnerRequestGroup"></integration-partner-request>
    </div>
  </form>
</md-step>

子组件.html(摘录):

<div class="row p-row-padding">
  <div class="col-xs-6">
    <md-input-container class="p-full-width">
      <input mdInput
             ngModel name="name"
             #name="ngModel"
             required
             (change)="showForm()"
             placeholder="{{'WELCOME_WIZARD.PARTNER_NAME' | translate}}">
      <md-error *ngIf="name.touched && name.invalid">
        <span *ngIf="name.errors.required">
          {{'WELCOME_WIZARD.FIELD_REQUIRED' | translate}}
        </span>
        <span *ngIf="name.errors.pattern">
          {{'WELCOME_WIZARD.INVALID_FIELD_FORMAT' | translate}}
        </span>
      </md-error>
    </md-input-container>
  </div>
  <div class="col-xs-6">
    <md-input-container class="p-full-width">
      <input mdInput
             ngModel name="status"
             #status="ngModel"
             placeholder="{{'WELCOME_WIZARD.PARTNER_STATUS' | translate}}">
      <md-error *ngIf="status.touched && status.invalid">
        <span *ngIf="status.errors.required">
          {{'WELCOME_WIZARD.FIELD_REQUIRED' | translate}}
        </span>
        <span *ngIf="status.errors.pattern">
          {{'WELCOME_WIZARD.INVALID_FIELD_FORMAT' | translate}}
        </span>
      </md-error>
    </md-input-container>
  </div>
</div>

子组件.ts:

export class ChildComponent implements OnInit {

  @Input() public form: FormGroup;
  @Input() public model: NgModelGroup;
  @Input() public type: string;

  public formResult;
  public modelResult;

  constructor() {
  }

  ngOnInit() {
    this.formResult = this.form;
    this.modelResult = this.model;
  }

  public showForm() {
    console.log(this.formResult);
    console.log(this.modelResult);
  }

}

子组件中还有一个按钮,只有在必填字段不为空时才有效,但事实并非如此,因为modelResult 没有任何字段值...:

<button
  class="p-full-width"
  md-raised-button
  [disabled]="formResult.invalid"
  mdStepperNext>
  {{'WELCOME_WIZARD.NEXT' | translate}}
</button>

我做错了什么?

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    你做的一切都是正确的——除了 Angular 2/4 不支持它。如果您查看NgModel 的源代码,您会发现它包含这样的定义:

    constructor(@Optional() @Host() parent: ControlContainer,
              ...)
    

    这意味着 DI 容器只会在第一个 @Host() 之前查找此依赖项 - 你猜怎么着? - 你的子组件。这意味着 NgModel 不会找到您的表单,也不会注册自己。每个@Component() 都是一个主机,所以没有办法让它像这样工作。

    所以,你的选择在这里真的很有限:将所有表单部分收集到一个组件中,或者构建你自己的 NgModel 实现。

    正如@yurzui 指出的(谢谢!)有一个解决方案:click。我自己没有尝试过,但我不明白为什么它不起作用 - 它非常简单和优雅。

    【讨论】:

    • 我想我确实找到了解决问题的方法。我不知道它有多正确,但它就是这样。我的父母中有一个&lt;form&gt;,我的子组件中有一个&lt;form&gt;。我使用两种方式绑定将表单从子组件传递到父组件。我不确定这是否可行,以及我是否可以替代这样的表格。有cmets吗?
    • so there's no way to make it work like this. 我知道一种工作方式medium.com/@a.yurich.zuev/… 另见stackoverflow.com/questions/39242219/…
    • 这实际上是一个有趣的解决方案 - 但它仍然是某种解决方法,尽管我承认它非常优雅。感谢您指出。我会添加它来回答。
    • @yurzui 它的工作方式与将所有表单部件放在一个模板中的方式相同
    • @DenissM。只需使用form.valid,因为您不需要在子组件中有另一个表单,所有子组件都将成为父 ngForm 的一部分
    猜你喜欢
    • 1970-01-01
    • 2016-08-09
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 2017-12-17
    相关资源
    最近更新 更多