угловая подписка при нажатии кнопки «подписаться»

#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 обрабатывать подписки.