Angular - 响应式表单处于挂起状态
Angular - Reactive forms has pending state
我在一个 Angular 项目中,我使用的是反应形式。我想做的是添加我自己的验证器。为此,我需要检查该 ID 是否存在于数据库中。出于这个原因,我使用了一个异步验证器。如果 id 已经被另一个元素使用,那么它必须 return 一个错误。否则,表格将有效。
这是验证器。
export class ValidadorOperationId {
static createValidatorOperationId(name, operationListService: OperationsListService, time: number = 500): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors> => {
return timer(time).pipe(
switchMap(() => operationListService.getOperationsByUuid(name, control.value)),
map(res => {
return res ? { operationIdExist: true } : null
}
)
);
};
}
}
这就是我在组件中调用验证器的方式。
this.fb.group({
value: [this.operationDetails['operationid'], [Validators.required], ValidadorOperationId.createValidatorOperationId(this.nombre,this.operationListService)]
})
问题是控件有status: pending
,不知道是什么问题
如果您需要更多代码,请问我。
谁能帮帮我?
- Angular版本:8.2.14
- Rxjs 版本:6.5.3
2020 年 10 月 22 日更新
我检查过 status:pending
仅在服务没有 return 任何内容(错误 404)时出现
确保你的 getOperationsByUuid
return 至少是一个可观察的或一个承诺,即使你收到 404 错误。这可能是它卡在挂起状态的原因,因为这个函数没有 return 任何东西,所以你的 observable 不会发出。
注意水龙头运算符。如果此日志未打印,这就是它保持待处理状态的原因,因为它永远不会解析。
export class ValidadorOperationId {
static createValidatorOperationId(name, operationListService: OperationsListService, time: number = 500): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors> => {
return timer(time).pipe(
switchMap(() => operationListService.getOperationsByUuid(name, control.value)),
tap(res => console.log('this should print')),
map(res => {
return res ? { operationIdExist: true } : null
}
),
take(1) // not useful if getOperationsByUuid is an http call (http calls always complete)
);
};
}
}
要处理 404
或任何其他 http 错误,您可以使用 RxJS 的 catchError 运算符。下面是你的验证器的样子 -
export class ValidadorOperationId {
static createValidatorOperationId(name, operationListService: OperationsListService, time: number = 500): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors> => {
return timer(time).pipe(
switchMap(() => operationListService.getOperationsByUuid(name, control.value)
.pipe(catchError(err => of(null))), // <-- this is what you need
map(res => {
return res ? { operationIdExist: true } : null
}
)
);
};
}
}
我在一个 Angular 项目中,我使用的是反应形式。我想做的是添加我自己的验证器。为此,我需要检查该 ID 是否存在于数据库中。出于这个原因,我使用了一个异步验证器。如果 id 已经被另一个元素使用,那么它必须 return 一个错误。否则,表格将有效。
这是验证器。
export class ValidadorOperationId {
static createValidatorOperationId(name, operationListService: OperationsListService, time: number = 500): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors> => {
return timer(time).pipe(
switchMap(() => operationListService.getOperationsByUuid(name, control.value)),
map(res => {
return res ? { operationIdExist: true } : null
}
)
);
};
}
}
这就是我在组件中调用验证器的方式。
this.fb.group({
value: [this.operationDetails['operationid'], [Validators.required], ValidadorOperationId.createValidatorOperationId(this.nombre,this.operationListService)]
})
问题是控件有status: pending
,不知道是什么问题
如果您需要更多代码,请问我。
谁能帮帮我?
- Angular版本:8.2.14
- Rxjs 版本:6.5.3
2020 年 10 月 22 日更新
我检查过 status:pending
仅在服务没有 return 任何内容(错误 404)时出现
确保你的 getOperationsByUuid
return 至少是一个可观察的或一个承诺,即使你收到 404 错误。这可能是它卡在挂起状态的原因,因为这个函数没有 return 任何东西,所以你的 observable 不会发出。
注意水龙头运算符。如果此日志未打印,这就是它保持待处理状态的原因,因为它永远不会解析。
export class ValidadorOperationId {
static createValidatorOperationId(name, operationListService: OperationsListService, time: number = 500): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors> => {
return timer(time).pipe(
switchMap(() => operationListService.getOperationsByUuid(name, control.value)),
tap(res => console.log('this should print')),
map(res => {
return res ? { operationIdExist: true } : null
}
),
take(1) // not useful if getOperationsByUuid is an http call (http calls always complete)
);
};
}
}
要处理 404
或任何其他 http 错误,您可以使用 RxJS 的 catchError 运算符。下面是你的验证器的样子 -
export class ValidadorOperationId {
static createValidatorOperationId(name, operationListService: OperationsListService, time: number = 500): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors> => {
return timer(time).pipe(
switchMap(() => operationListService.getOperationsByUuid(name, control.value)
.pipe(catchError(err => of(null))), // <-- this is what you need
map(res => {
return res ? { operationIdExist: true } : null
}
)
);
};
}
}