【问题标题】:Using Angular's `useExitsing` with custom form validations?使用带有自定义表单验证的 Angular `useExisting`?
【发布时间】:2018-02-27 07:57:32
【问题描述】:

阅读 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”。 如果你用useClass 替换useExisting,那么你就是 注册一个新的类实例,一个没有 forbiddenName.

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

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

另外,注册一个新的类实例怎么会没有forbiddenName?它是其中的一个属性!

问题:

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

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

The online demo

【问题讨论】:

  • 问题出在哪里?是否在单元测试中?
  • @ramesh 没有。我只是不明白哪个现有提供商已经拥有该物业,他们的意思是。我没有通过操作流程 pov 看到这里发生了什么

标签: javascript angular


【解决方案1】:

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

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

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

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

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


在了解提供者NG_VALIDATORSuseExisting的同时,还要寻找注入的地方,先看here

NG_VALIDATORSform 指令中注入,以便在验证表单时被调用。如下所述,这里您必须使用useExisting 才能获得forbiddenName 它只存在于使用该指令的创建实例上,否则@Input 字段将是未定义的。

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

【讨论】:

  • 这个答案包含引用问题的部分......(恕我直言)。它仍然没有解释流程。
  • @RoyiNamir 我已经添加了一些关于您的问题的详细信息,希望对您有所帮助。 :-) 顺便说一句,我建议您在 angular 包中放置一些断点以帮助理解这些问题。 :-)
  • 哦,这是我错过的缺失部分:只会在您的组件中使用时创建。所以它不像是注入时创建的服务,而是在第一次遇到标记时创建的,对吗???
  • @RoyiNamir 是的,指令与组件具有相同的生命周期。
猜你喜欢
  • 2021-06-22
  • 2017-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-01
  • 2012-10-05
  • 2012-11-21
相关资源
最近更新 更多