Angular 角度2事件侦听器条件竞争

Angular 角度2事件侦听器条件竞争,angular,dom-events,angular2-forms,angular2-directives,race-condition,Angular,Dom Events,Angular2 Forms,Angular2 Directives,Race Condition,我有一个指令appValidateOnChange,它实现 @HostListener('focus') onFocus() { this.validators = this.formControl.control.validator; this.asyncValidators = this.formControl.control.asyncValidator; this.formControl.control.clearAsyncValidators(); th

我有一个指令
appValidateOnChange
,它实现

@HostListener('focus') onFocus() {
    this.validators = this.formControl.control.validator;
    this.asyncValidators = this.formControl.control.asyncValidator;
    this.formControl.control.clearAsyncValidators();
    this.formControl.control.clearValidators();
}
@HostListener('change') onChange() {
    this.formControl.control.setAsyncValidators(this.asyncValidators);
    this.formControl.control.setValidators(this.validators);
    this.formControl.control.updateValueAndValidity();
}
目标是等待用户在验证输入之前完成输入。我就是这么说的

<input
        type="text"
        class="form-control"
        id="field"
        name="field"
        [ngModel]="fieldValue"
        #fieldName="ngModel"
        required
        minlength="8"
        (change)="updateField(fieldName)"
        appValidateOnChange>
问题是,两个
change
事件之间存在竞争条件

有时一切都按预期进行,因为指令的事件首先触发,而另一些时候则忽略验证,因为指令的事件第二次触发


我如何解决这个问题?我希望避免
setTimeout

当控件具有焦点时,我不会显示验证结果,而在发生默认验证时完全忽略


使用焦点和模糊事件来设置/清除标志,并在设置标志时隐藏验证警告(使用
*ngIf
[hidden]=“myFlag”

当控件具有焦点时,我将不显示验证结果,而在发生默认验证时完全忽略


使用焦点和模糊事件设置/清除标志,并在设置标志时隐藏验证警告(使用
*ngIf
[hidden]=“myFlag”

如果您已升级到Angular 5,则添加了一个新功能以仅在
模糊上进行验证,例如:


我建议您参考标题下的文档查看Angular Forms adds updateOn Blur/Submit


如果您已升级到Angular 5,则会添加一个新功能以仅在
blur
上进行验证,例如:


我建议您参考标题下的文档查看Angular Forms adds updateOn Blur/Submit


我不确定使用模板驱动的表单是否可以实现这一点。使用来自的反应式表单,您可以做到:

模板:

组成部分:

update(name: string) {
    this.form.controls[name].updateValueAndValidity();
}

我不确定使用模板驱动的表单是否可以做到这一点。使用来自的反应式表单,您可以做到:

模板:

组成部分:

update(name: string) {
    this.form.controls[name].updateValueAndValidity();
}

我认为如果你使用ngModelChange而不是change,就像你使用ngModel一样, 然后始终首先触发指令:
HTML

<input myDirective
        type="text"
        class="form-control"
        id="field"
        name="field"
        [ngModel]="fieldValue"
        #fieldName="ngModel"
        required
        minlength="8"
        (ngModelChange)="updateField(fieldName)"
        appValidateOnChange>

我认为如果您使用ngModelChange而不是change,就像您使用ngModel一样, 然后始终首先触发指令:
HTML

<input myDirective
        type="text"
        class="form-control"
        id="field"
        name="field"
        [ngModel]="fieldValue"
        #fieldName="ngModel"
        required
        minlength="8"
        (ngModelChange)="updateField(fieldName)"
        appValidateOnChange>


您是否可以检查表单提交而不是live上的数据的有效性?您是否尝试将HostListener放置到指令或输入中的
输入
事件而不是
更改
事件?这样,您的指令和
更新字段中的事件将不同,而不是2个侦听器是一样的吗event@Cacoon我很想这样做,遗憾的是,这个项目的规格不包括表单-一旦用户更改某些内容,必须立即触发更新(我讨厌它,tbh)@OsmanCea我尝试了
blur
事件,但它在
change
事件之后,我绝对需要在更改时调用更新函数,而不是blur…如果我没有弄错的话,
input
事件每次输入一个键时都会触发,对吧?如果是这样的话,它就不适合在第一次按键后触发验证,而h不是我要完成的内容。是否可以将组件中的更改移动到一个服务,该服务在指令完成onChange()后立即运行?因此,您确定要按您希望的顺序运行这两个更改?您是否可以检查表单提交而不是live上的数据的有效性?您是否尝试将HostListener放置到指令或输入中的
输入
事件而不是
更改
事件?这样,您的指令a中就会有一个不同的事件nd位于
updateField
中,而不是相同的两个侦听器event@Cacoon我很想这样做,遗憾的是,这个项目的规格不包括表单-一旦用户更改某些内容,必须立即触发更新(我讨厌它,tbh)@OsmanCea我尝试了
blur
事件,但它在
change
事件之后,我绝对需要在更改时调用更新函数,而不是blur…如果我没有弄错的话,
input
事件每次输入一个键时都会触发,对吧?如果是这样的话,它就不适合在第一次按键后触发验证,而h不是我要完成的内容。是否可以将组件中的更改移动到一个服务,该服务在指令完成onChange()后立即运行?那么您确定要按您希望的顺序运行这两个更改吗?好的,这看起来很有趣,所以我尝试升级…但遇到了无数问题。更新方式中存在漏洞,我的一些第三方组件还不兼容,等等…我认为我不能立即使用Angular 5 Yok,这似乎很有趣,所以我没有ried需要升级…但遇到了无数的问题。更新方式中存在漏洞,我的一些第三方组件还不兼容,等等…我不认为我将能够立即使用Angular 5,但这将按字段添加2个事件侦听器,这不会影响性能吗?此外,我不希望最初在在用户将原始事件从字段中删除后,我想我可以对此进行调整。最初我根据这里的答案进行调整:您已经有2个事件侦听器。您不需要添加更多。这不会影响性能。它工作得非常好。这不完全是我想要的,但现在可以。我可能会尝试升级请转到5.0,然后重试提供给我的另一个解决方案。谢谢!但这会按字段增加两个事件侦听器,这不会影响性能吗?此外,我不希望验证最初显示,只有在用户将原始内容从字段中取出后才显示…我想我可以对此进行调整。最初我根据答案h进行调整ere:您已经有2个事件侦听器。您不需要添加更多。它不会影响性能。它正在工作