如何在 Angular 2.0 中创建自定义验证指令(即用于验证的属性)?

How do I create a custom validation directive (i.e. attribute for validation) in Angular 2.0?

我正在使用 TypeScript 为 Angular 2.0 开发一个小项目。目前,据我了解,Angular 2.0 没有针对 "min" 和 "max" 标签的内置验证器。我了解如何构建自定义验证器并使用 FormBuilder 附加它,但我希望了解如何创建可附加到属性的自定义验证器指令。 HTML 看起来像这样:

 <div class="unit">
<div class="label">Age (13 - 120):</div>
<div class="labelTarget">
    <input id="ageFrm" min="13" max="120" type="number" required=""
    ng-control="age" #age="form" [class.error]="!age.valid"
    [(ng-model)]="ageValue"/> {{age.valid}}
</div>
</div>

现在 age.valid 始终是 true,因为 minmax 没有验证器。我尝试创建自己的。首先是自定义验证函数:

import {Control} from "angular2/angular2";

export class HealthAppCustomValidators {

static min(min: number): Function {
  return (control: Control): {[key: string]: any} => {
    var v: number = Number(control.value);
    console.log("validating " + v + " against " + min);
    return v < min ?
              {"min": {"requiredMin": min, "actualMin": v}} :
              null;
  };
  }

static max(max: number): Function {
  return (control: Control): {[key: string]: any} => {
var v: number = Number(control.value);
    return v > max ?
              {"max": {"requiredMax": max, "actualMax": v}} :
              null;
  };
   }
}

接下来是指令(这是基于检查源代码):

import {Attribute, Control, Directive, forwardRef, Provider, NG_VALIDATORS}   from "angular2/angular2";
import {HealthAppCustomValidators} from "./customValidators";

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

@Directive({
  selector: '[min][ng-control],[min][ng-form-control],[min][ng-model]',
  providers: [MIN_VALIDATOR]
})
export class MinValidator {

  private _validator: Function;

  constructor(@Attribute("min") min: string) {
    console.log(min);
    this._validator = HealthAppCustomValidators.min(Number(min));
  }
  validate(c: Control): {[key: string]: any} { 
    console.log("validate");
    return this._validator(c); 
 }
}

但是,每当我实际导入指令时,页面加载都会失败并出现以下错误:

TypeError: validator is not a function
at     http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:12990:24
at Array.reduce (native)
at Function.ListWrapper.reduce (http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:4206:19)
at http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:12989:44
at http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:12990:24
at Array.reduce (native)
at Function.ListWrapper.reduce (http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:4206:19)
at Control.validator (http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:12989:44)
at Control.AbstractControl.updateValidity (http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:18871:27)
at  http://127.0.0.1:8080/node_modules/angular2/bundles/angular2.dev.js:14097:14

非常感谢在没有 FormBuilder 的情况下以正确的方式执行此操作的任何帮助:

根据 Jeremy 的建议,

自从他们添加 support for Validator 的 alpha 45 后,问题就解决了。虽然错误消息可能令人困惑(你提供了一个函数,为什么不起作用?)但提交消息提供了线索

Currently, the only way for a directive to export a validator is by providing a function. This makes it ackward to write validators that depend on directive inputs. In addition to supporting functions as validators, classes implementing the Validator interface are supported too.

我无法在 alpha 44 或更低版本中找到自定义验证器的示例,因此我无法说明它们当时是如何工作的。而且他们很可能更新了所有示例和工作验证器以使用 alpha 45+。

无论如何,这是通过将 angular2 升级到最新版本解决的(顺便说一句,alpha 48 是最新版本,我在评论中说了 alpha 47,我的错)尽管它至少需要 alpha 45。