【问题标题】:Angular2 custom validator not called未调用Angular2自定义验证器
【发布时间】:2016-12-04 14:58:57
【问题描述】:

我已经编写了一个这样的自定义验证指令:

const DURATION_VALIDATOR = new Provider(
    NG_VALIDATORS,
    {useExisting: forwardRef(() => DurationDirective), multi: true}
);


@Directive({
    selector: '[ngModel][duration], [formControl][duration]',
    providers: [{
        provide: NG_VALIDATORS,
        useExisting: forwardRef(() => DurationDirective),
        multi: true }]
})
export class DurationDirective  implements Validator{
    constructor(public model:NgModel){
        console.error('init')
    }
    validate(c:FormControl) {
        console.error('validate')
        return {'err...':'err...'};
    }
}

我的 Html 看起来像这样:

<input 
    type="text"
    [(ngModel)]="preparation.duration"
    duration 
    required
>

我的问题是,当验证器被初始化时,即“init”被记录到控制台,验证函数从未被调用,即“验证”在输入字段时从未被记录到控制台。由于验证器已初始化,我假设我正确地“连接”了所有内容。那么缺少什么?

【问题讨论】:

    标签: forms validation typescript angular custom-validators


    【解决方案1】:

    我最好的选择是你没有在表单方面引导 Angular:

    import { App } from './app';
    import { disableDeprecatedForms, provideForms } from '@angular/forms';
    
    bootstrap(App, [
        // these are crucial
        disableDeprecatedForms(),
        provideForms()
      ]);
    

    您可以看到这个plunk - 它确实将"validate" 输出到控制台。

    【讨论】:

    • 我已将 disableDeprecatedForms()、provideForms() 添加到我的组件提供程序属性中。但这似乎没有任何效果。你能解释一下为什么吗?这是我更新的 plunk plnkr.co/edit/ztuBIZc3QMRwMg62scZR?p=preview
    • 那个 plunk 在 bootstrap() 调用中仍然没有两个提供调用。将您在 providers 属性中的两个调用移动到 bootstrap 方法可以解决这个问题。 plnkr.co/edit/b2PipR?p=preview
    • 抱歉,误会了。我故意将提供调用从引导方法移动到 my-app 组件来说明我的问题:我的假设是向组件提供程序添加 2 个提供调用就足够了。你能解释一下为什么不吗?
    • 我为这个特殊问题创建了一个单独的问题:stackoverflow.com/questions/38687705/…
    • @batesiiic,你是如何让你的 plunk 工作的?当我尝试你所拥有的时,Broccoli 编译器抱怨 FormControl 和 Validator 没有定义,因为它们从未被导入。这是因为我已经加载了 "@angular/common": "2.0.0-rc.4" 而你的 plunk 直接从 CDN 加载了 'npmcdn.com/@angular'?哪个是不同的版本?我什至无法直接加载该 URL。
    【解决方案2】:

    我对@batesiiic 的 plunk 进行了分叉和改进:https://plnkr.co/edit/Vokcid?p=preview

    validate(c:FormControl) {
        console.error('called validate()')
        return parseInt(c.value) < 10 ? null : {
          duration: {message: 'Please enter a number < 10'}
        };
    }
    

    如果输入有效,validate() 方法必须返回 null,否则,它返回一个对象 { key: value, ... } 其中 key 是错误的类型, value 可以是您可以在模板中使用的任何内容生成错误消息。

    模板还包含一个 div,用于在输入无效时显示错误消息。

    【讨论】:

      【解决方案3】:

      而不是将自定义验证器函数编写为类/组件/指令方法, 在组件/指令之外编写自定义验证器应该可以工作。

      validate(c:FormControl) {
          console.error('validate')
          return {'err...':'err...'};
      }
      
      @Directive({
          selector: '[ngModel][duration], [formControl][duration]',
          providers: [{
              provide: NG_VALIDATORS,
              useExisting: forwardRef(() => DurationDirective),
              multi: true }]
      })
      export class DurationDirective  implements Validator{
          constructor(public model:NgModel){
              console.error('init')
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-15
        • 2017-10-03
        • 2018-01-19
        • 2015-01-02
        • 1970-01-01
        • 2017-06-28
        • 2020-09-22
        • 1970-01-01
        相关资源
        最近更新 更多