如何使用模板形式从Angular 2的父组件中触发子组件验证器 [英] How to trigger child component validators from parent component in Angular 2 using template forms

查看:527
本文介绍了如何使用模板形式从Angular 2的父组件中触发子组件验证器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Angular中的模板表单进行条件验证时遇到了麻烦.我创建了一个自定义的EmailInputComponent:

I'm having trouble with conditional validation using template forms in Angular. I've created a custom EmailInputComponent:

<div class="form-group" provide-parent-form>
  <label for="email">Email<span *ngIf="required">*</span></label>
  <input id="email"
         class="form-control"
         name="email"
         type="email"
         [(ngModel)]="emailAddress"
         #email="ngModel"
         maxlength="255"
         validateEmail
         [required]="required ? '' : null"/>
  <error [model]="email" [referencedValue]="emailAddress"></error>
</div>

托管在父MyFormComponent内:

which is hosted inside a parent MyFormComponent:

<form #form="ngForm" name="form" (ngSubmit)="onSubmit($event)">
  <fieldset>
    <email [(emailAddress)]="model.email" [required]="emailRequired()"></email> 
    <!-- select component here -->
  </fieldset>    
  <button type="submit" [disabled]="!form.form.valid">Send</button>
</form>

该表单还包含一个SelectComponent,用户可以在其中选择其首选的联系方式.如果用户选择电子邮件",则必须输入电子邮件.

The form also contains a SelectComponent where users can choose their preferred way of contact. If users select "email", the email input becomes mandatory.

您可以看到,父母中有一些逻辑 emailRequired 该功能可根据当前选择的首选联系方式动态计算电子邮件输入是否为强制性. 每当此选定值更改时,我都需要以某种方式触发电子邮件输入验证器.我怎样才能做到这一点?

As you can, see there is some logic going on in the parents emailRequired function that dynamically calculates whether an email input is mandatory or not based on the currently selected preferred way of contact. Whenever this selected value changes I need to somehow trigger the email input validators. How can I do that?

使用 @ViewChild ,我设法从MyFormComponent获得了EmailInputComponent.但是我现在不知道该怎么办...

Using @ViewChild I managed to get a hold of the EmailInputComponent from the MyFormComponent. But I don't know how to proceed now...

推荐答案

与此同时,我找到了解决方案.我的子组件现在引用了相应的FormGroup.

Meanwhile I found a solution. My child component now references the according FormGroup.

<email [(emailAddress)]="model.email" 
       [formGroup]="form.form" 
       [required]="emailRequired()">
</email>

通过FormGroup,您可以到达子组件实际的FormControl并在验证器标志的设置器内调用 updateValueAndValidity (在我的情况下为 set required ):

Via the FormGroup, you can then reach to the child components actual FormControl and call updateValueAndValidity inside the setter of the validator flag (set required in my case):

import {Component, EventEmitter, Input, Output} from '@angular/core';
import {FormGroup} from '@angular/forms';

@Component({
  selector: 'email',
  templateUrl: './email.component.html',
  styleUrls: ['./email.component.css']
})
export class EmailInputComponent {

  private _emailAddress: string;

  public _required = true;

  @Input()
  private formGroup: FormGroup;

  @Output()
  emailAddressChange = new EventEmitter();

  constructor() { }

  @Input()
  get emailAddress(): string {
    return this._emailAddress;
  }

  set emailAddress(value: string) {
    this._emailAddress = value;
    this.emailAddressChange.emit(this._emailAddress);
  }

  @Input()
  get required(): boolean {
    return this._required;
  }

  set required(value: boolean) {
    this._required = value;
    // this is where the magic happens
    const refEmailControl = this.formGroup.controls.email;
    if (refEmailControl) {
      refEmailControl.updateValueAndValidity(); // updates the validity state      
      refEmailControl.markAsTouched(); // necessary in my case to make UI render error message
    }
  }
}

这篇关于如何使用模板形式从Angular 2的父组件中触发子组件验证器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆