Я новичок в angular и застрял в сценарии, когда при загрузке страницы мне нужно запустить 4 разных API-интерфейса на ngOnit и иметь событие щелчка на той же странице при нажатии на событие, которое я хочу, чтобы оно остановило все предыдущие вызовы и делает новый вызов API.
Код.
ngOnInit(): void {
this.getData('');
}
getData(data) {
const amount$ = this.service.getAmount(data).pipe(takeUntil(this.unSubscribe$));
const rate$ = this.service.getRate(data).pipe(takeUntil(this.unSubscribe$));
const applications$ = this.service.getApp(data).pipe(takeUntil(this.unSubscribe$));
const statistics$ = this.service.getStat(data).pipe(takeUntil(this.unSubscribe$));
applications$.subscribe(res => {
if (res.success) {
let d = res.dataSet;
}
}, (err) => {
})
------ and another three subscribe here
}
HTML
<button type = "button" (click) = "getData('abc')"
>Event</button>
«abc» — это динамическая строка, которая изменяется в соответствии с необходимостью, а затем нажимаем кнопку, мы передаем уникальную строку в функцию getData, и на основе этой строки мы получаем новый вызов API при каждом нажатии на кнопку, но я хотите, чтобы при каждом щелчке он останавливал все предыдущие вызовы API и нажимал новый.
Да в onDestroy
Это типичный сценарий для оператора switchMap
.
Я бы сделал что-то вроде этого
// define a BehaviorSubject, i.e. a subject that emits a first vale as soon as
// it is subscribed. In this case it emits an empty string, as in the ngOnInit
start$ = new BehaviorSubject<string>('')
// then define the Observable that runs the APIs with start$ as its starting point
execute$ = start$.pipe(
// here you place switchMap which means: as soon as I get a value from
// upstream, I unsubscribe and preceding subscription and start a new subscription
switchMap(val => {
// with merge here I run all the 3 APIs concurrently
return merge(
this.amount$(val),
this.rate$(val),
this.applications$(val),
this.statistics(val)$
)
})
)
Каждый Observable, который запускает API, должен быть возвращен функцией, которая принимает строку в качестве входных данных, чтобы мы могли использовать значение, переданное нажатием кнопки, например:
сумма$ = (данные) => { вернуть this.service.getAmount(данные); };
Если это http-вызов, вам не нужны takeUntil
и логика отписки, так как http-клиент, который предоставляет Angular, либо выдает один раз, а затем сразу завершается, либо выдает ошибки, поэтому отписка не нужна.
Теперь в ngOnInit вы создаете одну и только одну подписку, вот так
ngOnInit(): void {
this.execute$.subscribe(// whatever is necessary)
}
и в обработчике события нажатия кнопки вы next
start$
Тема, то есть вы заставляете start$
испускать строку, которую вы хотите
<button type = "button" (click) = "start$.next('abc')"
>Event</button>
Вы можете найти пример (с имитацией http-вызовов) здесь.
Спасибо @Picci за ответ ... Для этого я могу получить все ответы API одновременно, но я хочу получить данные, если какой-либо API отправит ответ.
Что вы имеете в виду, говоря, что я хочу получать данные, если какой-либо API отправляет ответ? Каково желаемое поведение?
вы отписываетесь от наблюдателя?