Хороший вопрос.Я знаю, что сначала сложно работать с RxJ, но когда вы освоите его, он станет достаточно мощным.
То, что вы хотите, может быть достигнуто с помощью BehaviorSubject
.
Давайте найдемузнать, что такое Subject
, и перейти на BehaviorSubject
Тема: является эквивалентом EventEmitter и единственным способом многоадресной передачи значения или события нескольким наблюдателям
Для получения дополнительной информации, посмотрите на здесь
Итак, мы знаем, что Subject
похож на EventEmitter
.Когда кто-то подписывается на него, каждый раз, когда вы звоните subject.next(value)
, каждый подписчик получает новое значение.Однако поздние подписчики (то есть подписка на Subject
после вызова метода next
) не получат предыдущие значения.Именно здесь BehaviorSubject
появится на сцене.
Это похоже на Subject
, но когда новый подписчик подписывается на него, он выдаст предыдущее значение.Давайте использовать его в вашем коде.
export class DataBrokerService {
// do not expose your subject to other classes
private _transactions$: BehaviorSubject<Transaction[]> = new BehaviorSubject([]);
// instead provide it as an observable
public readonly transactions: Observable<Transaction[]> = this._transactions$.asObservable();
needUpdate = true;
constructor(private http: HttpClient) { }
ngOnInit() {
}
// just return the observable
getTransactions(): Observable<Transaction[]> {
if (needUpdate) {
this.updateTransactions();
}
return this.transactions;
}
// you can iterate over your transactions and filter them,
// but DO NOT ever subscribe to it within a service.
// Otherwise, other classes won't be able to retrieve the value.
getTransaction(id: number): Observable<Transaction> {
return this.getTransactions().pipe(
map(txns => txns.find(txn => txn.id === id))
);
}
// when you need to update the transactions,
// simply call this method
updateTransactions() {
this.http.get('transactions').subscribe(txns => {
this.needUpdate = false;
this._transactions$.next(txns);
});
}
}