【发布时间】:2019-10-10 09:26:34
【问题描述】:
查看下方更新
我意识到我的问题是我对 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(); 的建议,但是我返回了一个承诺,但我无法返回一个承诺,让验证器按照我的理解工作。
我该如何处理?
来自我的package.json:
"@angular/core": "7.1.0",
"@angular/forms": "7.1.0",
"rxjs": "6.3.3",
"rxjs-compat": "^6.4.0",
更新 5/23/19 尝试实施 @Sachin 的答案。 我在地图内的断点永远不会被击中。我没有得到任何控制台日志,即使我删除了地图中的逻辑并返回 null,它仍然总是返回无效。对这里发生的事情感到非常困惑。我的服务实际上被调用了,我已经确认了。
有什么想法吗?
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)]));
2019 年 6 月 7 日更新 #2
在https://www.youtube.com/watch?v=zeX5CtFqkXQ 之后,我能够制作一个基于指令的验证器,但如果您能够看到我在之前的更新中做错了什么,我仍然希望在我的 ts 中使用验证器。
@Directive({ 选择器:“[validFinalQty]”, 提供者:[{提供:NG_ASYNC_VALIDATORS,useExisting:ValidateFinalQtyDirective,多:真}] })
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)
);
}
【问题讨论】:
-
你能展示一下
getQty()的实现吗? -
.subscribe(x => console.log("subscribe output", x));此订阅错误。您应该在不订阅的情况下传递 observable
标签: angular rxjs angular-reactive-forms