关于Comparing fields in validator with Angular 2,请参考这question条.不幸的是,Angular 2稍微改变了一点,所以这个解决方案似乎不再起作用了.以下是我的代码:

import {IonicApp, Page, NavController, NavParams} from 'ionic/ionic'
import {Component} from 'angular2/core'
import {FORM_PROVIDERS, FormBuilder, Validators} from 'angular2/common'
import {ControlMessages} from '../../components/control-messages'
import {ValidationService} from '../../services/validation-service'

@Page({
  templateUrl: 'build/pages/account/register.html',
  directives: [ControlMessages]
})
export class RegisterPage {
  constructor(nav: NavController, private builder: FormBuilder) {
    this.nav = nav
    this.registerForm = this.builder.group({
      'name':     ['', Validators.required],
      'email':    ['', Validators.compose([Validators.required, ValidationService.emailValidator])],
      'password': ['', Validators.required],
      'repeat':   ['', this.customValidator]
      }
    )        
  }

  register() {    
    alert(this.registerForm.value.password)
  }

  private customValidator(control) {         
    //console.log(this.registerForm.value.password)
    //return {isEqual: control.value === this.registerForm.value.password}
    return true  
  }
}

我的html:

<ion-content class="account">
  <ion-list padding>
    <form [ngFormModel]='registerForm' (submit)='register()'>
      <div class="centered">
        <img class="logo" src="img/logo.png" alt="">
      </div>
      <div class="spacer" style="height: 20px;"></div>
    
      <ion-input>
        <ion-label floating>Name</ion-label>
        <input type="text" ngControl='name' id='name'>
        <control-messages control="name"></control-messages>            
      </ion-input>
    
      <ion-input>
        <ion-label floating>Email</ion-label>
        <input type="email" ngControl='email' id='email'>
        <control-messages control="email"></control-messages>               
      </ion-input>

      <ion-input>
        <ion-label floating>Password</ion-label>
        <input type="password" ngControl='password' id='password' value="">
        <control-messages control="password"></control-messages>        
      </ion-input>

      <ion-input>
        <ion-label floating>Confirm Password</ion-label>
        <input type="password" ngControl='repeat' id='repeat'>
        <control-messages control="repeat"></control-messages>                
      </ion-input>

      <button class="calm" full type='submit' [disabled]='!registerForm.valid'>Register</button>
    
      <ion-item style="background-color:transparent;border:none;">
        <button class="text-button" clear item-right (click)="gotoLogin()">Have an account already, Login</button>
      </ion-item>
    </form>
  </ion-list>

</ion-content>

但不幸的是,我无法访问验证函数中的password值.如果取消注释console.log(this.registerForm.value.password),则会收到以下错误消息:

异常:TypeError:无法读取未定义的属性"值"

知道吗?谢谢

推荐答案

我在您的代码中发现了几个问题.您try 在验证器函数中使用关键字this,但这与组件的实例不对应.这是因为在将其设置为验证器函数时引用了该函数.

此外,可以在value属性中达到与控件关联的值.

也就是说,我认为将两个字段一起验证的正确方法是创建一个组,并在其中关联一个验证器:

import { FormBuilder, Validators } from '@angular/forms';
...
constructor(private fb: FormBuilder) { // <--- inject FormBuilder
  this.createForm();
}
createForm() {
  this.registerForm = this.fb.group({
    'name' : ['', Validators.required],
    'email': ['', [Validators.required, Validators.email] ],
    'passwords': this.fb.group({
      password: ['', Validators.required],
      repeat:   ['', Validators.required]
    }, {validator: this.matchValidator})
  });    
}

这样你就可以访问该组的所有控件,而不仅仅是一个控件,并且不再需要使用this关键字...可以使用FormGroup的controls属性访问该组的表单控件.触发验证时提供FormGroup.例如:

matchValidator(group: FormGroup) {
  var valid = false;

  for (name in group.controls) {
    var val = group.controls[name].value
    (...)
  }

  if (valid) {
    return null;
  }

  return {
    mismatch: true
  };
}

有关更多详细信息,请参阅此向导:

Edit

要显示错误,只需使用以下命令:

<span *ngIf="!registerForm.passwords.valid" class="help-block text-danger">
  <div *ngIf="registerForm.passwords?.errors?.mismatch">
    The two passwords aren't the same
  </div>
</span>

Angular相关问答推荐

天使17中的倒计时器

如何将Angular 服务包含在延迟加载的独立组件路由中?

Angular 16+使用ngTemplateOutlet有条件地呈现几个模板中的一个

RxJS轮询+使用退避策略重试

Observable转换为Observable

重新打开模态时 ng-select 中的重复值 - Angular

使用 Observable 进行渐进式填充

Angular 获取视频持续时间并存储在外部变量中

Angular UNIVERSAL prerender 错误方法 Promise.prototype.then 调用不兼容的接收器 [object Object]

如何以Angular 改变环境

Angular:将间隔与增量和减量相结合

缺少 .angular-cli.json 文件:Angular

运行 npm 测试(Angular 2 单元测试)后无法读取未定义的属性 subscribe

Angular2 测试 - 按 ID 获取元素

如何在 Angular 4 中使用 Material Design 图标?

来自 ngFor 项的动态 routerLink 值给出错误Got interpolation ({{}}) where expression was expected

Angular 2 中的 OnChanges 和 DoCheck 有什么区别?

如何使用 Angular 6 工作的 ngModel 创建自定义输入组件?

在angular-cli中创建模块时生成路由模块

如何使用formControlName和处理嵌套的formGroup?