angular – 如何将异步验证器添加到CUSTOM字段?
有谁知道如何在自定义字段的类中声明ASYNC验证方法?
现在我在validate()方法中有一个同步验证器: @Component({ selector: 'my-field',template: `<p>Some markup</p>`,providers: [ { provide: NG_VALUE_ACCESSOR,useExisting: forwardRef(() => MyFieldComponent),multi: true },{ provide: NG_VALIDATORS,multi: true } ] }) export class MyFieldComponent implements ControlValueAccessor { validate(c: FormControl) { // return null or error } // Rest of the code omitted for brevity // writeValue(),registerOnChange()... } 但即使我使用与上面相同的语法将NG_ASYNC_VALIDATORS添加到提供程序,它也不允许我声明类似于validateAsync()方法. 除非……两种类型的验证器都以validate()方法为目标,我需要在此方法中同时执行同步和异步验证,并返回一个大的observable(可能包含多个错误键)?我对此不太确定. 侧面注意:我可以开始工作的是直接在提供者中声明异步验证器,可以使用useValue内联,也可以使用useClass作为单独的类.但是我希望将它作为使用useExisting的组件类的方法. 解决方法
我不完全明白你的要求是什么,但我可以给你一些想法,也许会帮助你.
所以让我们从实现ControlValueAccessor和Validator(sync)的自定义字段开始: @Component({ selector: 'my-field',multi: true } ] }) export class MyFieldComponent implements ControlValueAccessor,Validator { onChange = (_: any) => { }; onTouched = () => { }; constructor(private _renderer: Renderer,private _elementRef: ElementRef) { } writeValue(value: any): void { const normalizedValue = value == null ? '' : value; this._renderer.setElementProperty(this._elementRef.nativeElement,'value',normalizedValue); } registerOnChange(fn: (_: any) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } validationResult: any; validate(c: FormControl) { this.validationResult = { 'sync': true }; return null; } } 之后声明将实现AsyncValidator的指令: @Directive({ selector: 'my-field[formControlName],my-field[ngModel]',providers: [{ provide: NG_ASYNC_VALIDATORS,useExisting: forwardRef(() => CustomAsyncValidator),multi: true }] }) class CustomAsyncValidator implements AsyncValidator { valueAccessor: MyFieldComponent; constructor(@Optional() @Self() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[]) { this.valueAccessor = valueAccessors.find(x => x.constructor === MyFieldComponent) as MyFieldComponent; } // the same as above. I would use it // constructor(@Self() private valueAccessor: MyFieldComponent) {} /** * presents global validation result async + sync */ validate(control: AbstractControl): Observable<any> { return Observable.fromPromise(fakeAsyncValidator(1000)(control)).map(asyncResult => { return Object.assign({},asyncResult,this.valueAccessor.validationResult); }); } } function fakeAsyncValidator(timeout: number = 0) { return (c: AbstractControl) => { let resolve: (result: any) => void; const promise = new Promise(res => { resolve = res; }); const res = { 'async': false }; setTimeout(() => resolve(res),timeout); return promise; }; } 在上面的指令中,我们使用与自定义字段(my-field)相同的选择器,提供NG_ASYNC_VALIDATORS并在构造函数中注入现有组件(您可以注意到两个选项). 最后我们在这个指令中有验证方法,试图做你想要的类似的事情. Plunker Example (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |