查看下面的更新
我意识到我的问题是我对 observables 和 RxJS 非常陌生。
我有一个像这样的自定义验证器:
export function ValidateFinalQty(service: MyService) {
return (control: AbstractControl): { [key: string]: any } | null => {
let qty = service.GetQty();
if (control.value != qty) {
return { FinalQuantityNotMatching: true };
} else {
return null;
}
};
}
GetQty 返回一个 RxJS Observable。
那么我该如何设置,以便我的同步验证器根据异步调用返回正确的值?我需要验证器的返回类型保持为 { [key: string]: any } | null
.
我看到类似 qty = await service.GetQty().first().toPromise();
的建议但随后我返回了一个 promise ,但我无法返回一个让验证器按照我的理解工作的 promise 。
我该如何处理这个问题?
来 self 的package.json
:
"@angular/core": "7.1.0",
"@angular/forms": "7.1.0",
"rxjs": "6.3.3",
"rxjs-compat": "^6.4.0",
更新 2019 年 5 月 23 日尝试实现@Sachin 的答案。 我在 map 内的断点永远不会被击中。我没有收到任何控制台日志,即使我删除映射中的逻辑并返回 null,它仍然总是返回 invalid。对这里发生的事情非常困惑。我的服务实际上正在被调用,我已经确认了这一点。
有什么想法吗?
export class CustomAsyncValidator {
static ValidateFinalQty(qtyService: FinalQtyService, brf: BatchRecordForm): AsyncValidatorFn {
return (control: AbstractControl) => {
return qtyService.postCalcFinalQuanity(brf)
.pipe(
map((qty) => {
console.log("running qty validator. value:", qty);
if (control.value !== qty) {
return { FinalQuantityNotMatching: true };
} else {
return null;
}
}),
catchError((err) => {
console.log("Error in final quantity validator", err);
return null;
}),
finalize(() => console.log("finished"))
);
};
}
}
更新 2019 年 6 月 7 日
在订阅日志记录中,我得到了正确的答案(null 或 { FinalQuantityNotMatching: true }),但我的表单控件仍然无效。我做错了什么?
验证器.ts
export class CustomAsyncValidator {
static ValidateFinalQty(fqs: FinalQtyService, brf: BatchRecordForm) {
return (control: AbstractControl) => {
return fqs.postCalcFinalQuanity(brf).pipe(
debounceTime(500),
tap((action) => console.log("final qty", action)),
tap((action) => console.log("control.value", control.value)),
map(arr => (arr.Value !== `${control.value}`) ? { FinalQuantityNotMatching: true } : null)
).subscribe(x => console.log("subscribe output", x));
};
}
}
组件.ts
this.noteForm.addControl(this.finalQtyFormControlName, new FormControl(this.noteSubModuleForm.Value,
[Validators.required, CustomAsyncValidator.ValidateFinalQty(this.finalQtyService, this.embrService.batchRecordForm)]));
更新 6/7/2019 #2
已关注 https://www.youtube.com/watch?v=zeX5CtFqkXQ我能够制作一个基于指令的验证器,但如果您能够看到我在之前的更新中做错了什么,我仍然更喜欢在我的 ts 中使用验证器。
@指令({ 选择器:“[有效最终数量]”, 提供者:[{提供:NG_ASYNC_VALIDATORS,useExisting:ValidateFinalQtyDirective,multi:true}] })
export class ValidateFinalQtyDirective implements AsyncValidator {
constructor(private fqs: FinalQtyService, private embrService: EmbrService) { }
validate(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
return this.fqs.postCalcFinalQuanity(this.embrService.batchRecordForm).pipe(
tap(x => {
console.log("final qty", x);
console.log("control.value", control.value);
}),
map(arr => (arr.Value !== `${control.value}`) ? { FinalQuantityNotMatching: true } : null)
);
}
最佳答案
我有一个类似的Validator指令,让我根据你的代码进行调整:
看看它是否适合你
import { Directive } from '@angular/core';
import { NG_ASYNC_VALIDATORS, AsyncValidator, AbstractControl, ValidationErrors } from '@angular/forms';
import { MyService } from './MyService';
import { Observable, of as observableOf} from 'rxjs';
@Directive({
selector: '[qty-valid]',
providers: [{provide: NG_ASYNC_VALIDATORS, useExisting: QuantityValidatorDirective , multi: true}]
})
export class QuantityValidatorDirective implements AsyncValidator {
constructor(private service : MyService ) { }
validate(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
return new Promise((resolve, reject) => {
this.service.GetQty()
.subscribe( (qty: any) => {
if (control.value != qty) {
resolve({ FinalQuantityNotMatching: true })
} else {
resolve(null)
}
},error => resolve(null));
});
}
}
关于带有异步 RxJS 调用的 Angular 响应式(Reactive)表单自定义验证器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56281409/