#angular #rxjs
#угловая #rxjs
Вопрос:
В настоящее время у меня есть кнопка, при нажатии на которую я хочу вызвать службу:
saveAssignment(formValues) {
if (this.rulesService.validate(3, 1)) {
// continue to save
console.log('trigger save');
this.assignmentService.saveAssignment(formValues).subscribe((data) => {
console.log('saved!');
});
} else {
alert('came in here instead');
}
}
служба правил:
validate(actionId: number, referenceId: number): boolean {
let hasErrors = false;
let result: any;
this.validateRulesAPI(3, 1).subscribe((data) => {
// some logic here will set hasErrors property to true/false
});
return hasErrors;
}
ruleService, я хочу, чтобы он возвращал bool, независимо от того, подтвердил он параметры или нет, таким образом, я могу использовать это повторно, проблема в том, что порядок отключен, поскольку код возвращается до завершения вызова, это другой способ организовать это, чтобы они ждали друг друга? итак, rulesService.validate будет ждать возврата bool, а затем перейдет к вызову saveAssignments, если оно вернет значение true? в противном случае я вижу, что появляется предупреждение («вместо этого пришло сюда»), а затем выполняется код проверки.
Комментарии:
1. Способ вернуть асинхронный логический результат заключается в возврате наблюдаемого<boolean> . Вы не можете преобразовать асинхронный вызов в синхронный. Как только у вас есть логическое значение observable, вы можете применять операторы (filter, например, для выполнения чего-либо, только если логическое значение равно true, и switchMap для объединения другого наблюдаемого).
Ответ №1:
Вы можете использовать switchMap
конвейерный оператор rxjs
для подписки на внутреннюю наблюдаемую.
Для проверки вы можете вернуть значение, Observable
которое сопоставлено с boolean
соответствующим образом:
validate(actionId: number, referenceId: number): Observable<boolean> {
return this.validateRulesAPI(actionId, referenceId).pipe(map(data) => {
// Do the stuff and check for errors
// if has error then ------------> return false
// if does not have error then ---> return true
});
}
Затем в saveAssignment
методе вы можете использовать switchMap
saveAssignment(formValues) {
this.rulesService.validate(3, 1).pipe(
switchMap((isValid) => {
if(isValid){
return this.assignmentService.saveAssignment(formValues)
}else{
return of(false); // false or whatever the value you want to have
}
})
).subscribe((response) => {
if(response === false){
alert('Invalid'); // alert('came in here instead');
}else{
console.log(response); // response of this.assignmentService.saveAssignment(formValues)
}
})
Надеюсь, это поможет.
Комментарии:
1. Да, это сработает, но я хочу, чтобы saveAssignments выполнялись вне validate, поскольку я хочу повторно использовать validate в нескольких вызовах. например, я хочу вызвать validate перед сохранением подписей, saveXYZ, saveABC. я хочу подтвердить, чтобы сообщить мне, можно ли переходить к сохранениям.
2. Таким образом, ее уже можно повторно использовать. Переменная isValid является ответом на проверку. Все, что вам нужно сделать, это изменить вызываемый метод в switchMap, чтобы повторно использовать его с любой другой асинхронной операцией
Ответ №2:
Вы выполняете асинхронную проверку. Она немного отличается от синхронной.
В руководстве по проверке формы Angular есть объяснение того, как справиться с этим видом проверки, которое позволит вам разрешить Angular обрабатывать подписки.