Angular中如何捕获属性指令的输出事件并展示自定义提示信息
解决方案
你可以根据实际需求选择以下任意一种方式实现校验事件捕获和自定义提示:
1. 直接使用表单控件自带的状态变更事件捕获校验结果
Angular的NgModel实例自带statusChanges可观察对象,会在校验状态变更时触发,你可以直接订阅这个流获取校验结果:
首先在组件代码中获取title输入框的NgModel实例:
import { ViewChild, AfterViewInit } from '@angular/core'; import { NgModel } from '@angular/forms'; // 类内部代码 @ViewChild('title') titleControl: NgModel; ngAfterViewInit() { // 订阅校验状态变更事件 this.titleControl.statusChanges.subscribe(status => { // 校验失败且是自定义的重复标题错误时触发逻辑 if (status === 'INVALID' && this.titleControl.hasError('vueCustomValidation')) { const errorMsg = this.titleControl.getError('vueCustomValidation'); // 这里写你需要的自定义逻辑,比如弹全局提示、修改页面样式等 } }); }
2. 直接修改提示组件绑定,自动展示自定义错误
你当前HTML里的<vue-validation-message>组件,vueCustomValidation属性绑定的是error.requiredTitle,和你指令返回的重复标题错误不匹配,直接修改绑定值即可自动展示对应的自定义提示,无需额外逻辑:
<vue-validation-message i18nBundle="ClientPublishing" required="error.requiredTitle" vueValidateLength="error.maxErrorTitle" <!-- 把这里的属性值改成你指令里用的重复标题错误key --> vueCustomValidation="error.duplicateTitle" [control]="title" [formError]="formError"> </vue-validation-message>
3. 给自定义指令新增Output事件往外传递校验失败通知
如果需要在指令内部触发校验失败时主动通知外层组件,可以给指令增加自定义输出事件:
首先修改duplicate-title.ts代码:
import { Output, EventEmitter } from '@angular/core'; @Directive({ selector: '[duplicateTitle]', providers: [{provide: NG_VALIDATORS, useExisting: DuplicateTitleDirective, multi: true}] }) export class DuplicateTitleDirective implements Validator { @Input('duplicateTitle') duplicateTitle:Object; // 新增自定义输出事件 @Output() validationFail = new EventEmitter<string>(); constructor(private el: ElementRef,private vueTranslationService: VueTranslationService){} validate(control: AbstractControl): ValidationErrors | null { const isDuplicate = this.isDuplicateTitleExist(this.duplicateTitle['ds'], (this.el.nativeElement as HTMLInputElement).value,this.duplicateTitle['id']); if (isDuplicate) { const errMsg = this.getTranslation('error.duplicateTitle'); // 校验失败时触发事件,把错误信息传出去 this.validationFail.emit(errMsg); return {vueCustomValidation: errMsg}; } return null; } // 你原代码的遍历逻辑存在bug,只会校验第一个子节点,修改后如下 private isDuplicateTitleExist(node,title,id):boolean{ if(node && node.sectionTitle === title && node.id !== id){ return true; } if(node && node.subExamSections){ for(let i=0 ;i< node.subExamSections.length;i++){ if(this.isDuplicateTitleExist(node.subExamSections[i],title,id)) { return true; } } } return false; } public getTranslation(key: string): string | null { return this.vueTranslationService.getTranslation('ClientPublishing', key); } }
然后在HTML的input标签上绑定这个事件:
<input autocomplete="off" class="inpt-width100pc" autofocus name="title" required vueMaxLength="250" [duplicateTitle]="{ds:dataSource.data[0],id:selectednode.id}" #title="ngModel" <!-- 绑定自定义校验失败事件 --> (validationFail)="handleDuplicateError($event)" [(ngModel)]="selectednode.sectionTitle" id="title" aria-required="true">
最后在组件里实现对应的处理方法即可:
handleDuplicateError(errMsg: string) { // 这里写你需要的自定义处理逻辑 }
内容的提问来源于stack exchange,提问作者Ajay K
相关产品推荐
相关产品推荐

