angular 2 表单元素作为组件 - 验证不起作用

Posted

技术标签:

【中文标题】angular 2 表单元素作为组件 - 验证不起作用【英文标题】:angular 2 form elements as components - validation doesnt work 【发布时间】:2017-09-06 11:25:38 【问题描述】:

我在我的项目中实现了这个解决方案http://blog.rangle.io/angular-2-ngmodel-and-custom-form-components/ 基本上你用表单元素构建一个组件并将其放入表单中,我遇到的问题是,当我想构建一个检查字段之间依赖关系的验证器时

import Directive, Attribute from '@angular/core';

    import 
      NG_VALIDATORS,
      AbstractControl,
     from '@angular/forms';

    @Directive(
      selector: '[validateEqual][ngModel]',
      providers: [
        provide: NG_VALIDATORS, useExisting: ParentFieldNotNullValidator, multi: true
      ]
    )
    export class ParentFieldNotNullValidator 
      constructor(@Attribute('validateEqual') public validateEqual: string) 
      

      validate(c: AbstractControl): [key: string]: any 
        if (!c.value) 
           return null;
        
        let e = c.root.get(this.validateEqual);

        if (e && e.value) 
          console.log('ERROR 1');
          return null;
        
        console.log('error 2');
        return validateError: "message" 

在常规模板驱动形式中它的作品,但在这个实现中它没有,我得到这种流 screenshot from webbrowser

当父字段存在且不为空时,此验证器应仅写入 'ERROR 1'

我做错了什么? 我的html

<form #form="ngForm" (ngSubmit)="onSubmit(form.value)">
  <div class="u-space-bottom-8">
    <form-input
      cannotContainSpace
      minlength="4"
      required
      name="username"
      [(ngModel)]="user.username">
      >
    </form-input>
  </div>
  <div class="u-space-bottom-8">
    <form-input
      validateEqual="username"
      type="password"
      required
      name="password"
      [(ngModel)]="user.password">
      >
    </form-input>
  </div>
  <button
    class="c-btn c-btn--default u-h-10 u-bg-gray-16 u-paint-white-1"
    type="send"
    [disabled]="!form.valid"
  >
    'btn_login'|translate
  </button>
</form>

【问题讨论】:

“不起作用”到底是什么意思? 我编辑了我的问题 当我改变这部分时它的非常奇怪的行为:if (e &amp;&amp; e.value) 到这个if (e.value) 我得到一个错误 TypeError: Cannot read property 'value' of null 所以我的结论是不是有时父字段存在,有时不存在:/但为什么? 我有同样的错误。我相信这是因为 c.root 出于某种原因是对 c 本身的引用,它显然没有标识符为“用户名”的子元素。我将使用您的解决方案,但我希望将来有人会发现这里出了什么问题。 【参考方案1】:

我找到了解决方案,问题出在数据绑定上,现在我的验证器如下所示:

import Directive, Input from '@angular/core';

import 
  NG_VALIDATORS,
  AbstractControl,
 from '@angular/forms';

@Directive(
  selector: '[validateEqual][ngModel]',
  providers: [
    provide: NG_VALIDATORS, useExisting: ParentFieldNotNullValidator, multi: true
  ]
)
export class ParentFieldNotNullValidator 
  constructor() 
  
  @Input('validateEqual') parentValue: string;
  validate(c: AbstractControl): [key: string]: any 
    if (!c.value) 
      return null;
    
    if (this.parentValue) 
      return null;
    
    return parentFieldNotNull: "message"
  

html看起来像这样

<form #form="ngForm" (ngSubmit)="onSubmit(form.value)">
  <div class="u-space-bottom-8">
    <form-input
      cannotContainSpace
      minlength="4"
      required
      name="username"
      [(ngModel)]="user.username">
      >
    </form-input>
  </div>
  <div class="u-space-bottom-8">
    <form-input
      [validateEqual]="user.username"
      type="password"
      required
      name="password"
      [(ngModel)]="user.password">
      >
    </form-input>
  </div>
  <button
    class="c-btn c-btn--default u-h-10 u-bg-gray-16 u-paint-white-1"
    type="wyslij"
    [disabled]="!form.valid"
  >
    'btn_login'|translate
  </button>
</form>

【讨论】:

以上是关于angular 2 表单元素作为组件 - 验证不起作用的主要内容,如果未能解决你的问题,请参考以下文章

带有子组件和验证的 Angular 2 嵌套表单

为啥这种带有动态输入值的表单验证不起作用?

Angular DatePicker 的 Kendo UI 验证不起作用

Angular 2 innerHTML 忽略表单标签

在 Angular 2 中,当我尝试使用两种方式绑定时,ngIF 不起作用

Angular 2 表单验证器弄乱了取消按钮