使用Angular的`useExitsing`和自定义表单验证?

时间:2018-02-27 07:57:32

标签: javascript angular

阅读Angular有关adding custom validators to template-driven forms的文档 - 有一个简单的例子, custom 用以下方式验证输入:

  • 必需
  • = MINLENGTH “4”
  • 值不应包含“bob”

标记:

<input id="name" name="name" 
       required minlength="4" appForbiddenName="bob"
       [(ngModel)]="hero.name" #name="ngModel" >

指令:

@Directive({
  selector: '[appForbiddenName]',
  providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}]
})
export class ForbiddenValidatorDirective implements Validator {
  @Input('appForbiddenName') forbiddenName: string;

  validate(control: AbstractControl): {[key: string]: any} {
   ...
  }
}

代码很清楚。 他们也说:

  

您可能已经注意到自定义验证指令是   使用useExisting而不是useClass进行实例化。已注册   验证器必须是ForbiddenValidatorDirective的这个实例 -   表单中的实例,其forbiddenName属性绑定到“bob”。   如果您要将useExisting替换为useClass,那么您就是   注册一个新的类实例,一个没有的实例   forbiddenName

现在 - 我知道 useExistsinguseValue之间有什么区别。

但他们谈论的是哪个现有实例?如果useExistsing找不到匹配项,则会创建一个......所以?

此外,如何注册新的类实例不会有forbiddenName?它是一个属性!

问题:

我不明白这里发生的操作顺序是什么 谁创建了第一个实例,稍后由指令代码使用useExisting?

(以某种方式,如果我使用useClass,它将创建另一个不包含属性的实例....(???))

The online demo

1 个答案:

答案 0 :(得分:1)

ForbiddenValidatorDirective实例仅在组件中使用时创建。 useExisting只会确保使用确切的实例 保留@Input字段。

  

我不明白这里发生的操作顺序是什么。

  1. 在您的组件中使用了检测到Angular的ForbiddenValidatorDirective时,会创建@Input(带appForbiddenName字段)的实例。
  2. Angular尝试在创建NG_VALIDATORS指令的实例时检测form(检测到表单指令)。
  3.   

    如果我使用useClass,它将创建另一个不包含属性的实例....(???)

    对于useClass,Angular会将ForbiddenValidatorDirective视为普通类,并按new ForbiddenValidatorDirective()创建实例,而此处@Input将被忽略。

    在了解提供商 NG_VALIDATORS useExisting时,我们应该查找注入的位置,请先查看here

    NG_VALIDATORS注入form指令,以便在对表单进行验证时调用。如下所述,此处您必须使用useExisting才能获得forbiddenName 仅存在于使用该指令的实例上,否则@Input已归档将是未定义的。

      

    已注册   验证器必须是ForbiddenValidatorDirective的这个实例 -   表单中的实例,其forbiddenName属性绑定到“bob”。   如果您要将useExisting替换为useClass,那么您就是   注册一个新的类实例,一个没有的实例   forbiddenName