Ваш статический массив не может выходить за рамки вашего сервиса. Однако вы также не можете иметь static
внутри своего class scope
.
Поскольку services
в Angular по умолчанию равно singletons
, ваша целевая цель будет достигнута, если вы сделаете что-то вроде этого:
@Injectable()
export class FetchDataService {
creditorsStaticArray: Creditor[] = [];
getCreditorsFromAPI() {
this.http.get<Creditor[]>(this.creditorsUrl)
.subscribe(
items => {
this.creditorsStaticArray = items;
}
);
}
getCreds() {
return this.creditorsStaticArray;
}
}
Поскольку вы уже ссылаетесь на this.creditorsStaticArray
, это сразу сработает. Возможно, вы захотите переименовать его в creditorsCache
или что-то подобное и предотвратить прямой доступ к нему из-за пределов службы (сделав его private
), поскольку он больше не static
. Но помимо соглашений об именах и ограничителей доступа вы достигаете цели, которую ищете.
Теперь я добавлю несколько лучших практик внизу для вашего дальнейшего использования.
Вы подписываетесь внутри своего Сервиса и не управляете подпиской «явно». Это не обязательно плохо, так как HttpClient
по умолчанию завершится после первого результата, но, возможно, стоит сделать это более явным, добавив .pipe(first())
или .pipe(take(1))
(first
— это псевдоним take(1)
). Таким образом, если ваш API или способ извлечения данных изменится, появится явное напоминание о том, что этот Observable
примет 1 значение (весь массив) и завершится сам, сохранив результат в переменной в качестве побочного эффекта.
То, что вы, возможно, захотите рассмотреть, это не subscribing
внутри вашего Сервиса, а возврат всего Observable
вашим компонентам, чтобы он мог пройти и определить момент подписки. Вы все еще можете сохранить состояние своей переменной, поместив ее в
.pipe(
tap(data => { this.creditorsCache = data })
)
Когда вы или ваш компонент (или ваш HTML с помощью AsyncPipe
) подписывается; он сохранит его в своем кеше, и вы сможете автоматически обрабатывать новые входящие результаты.
В приведенном выше примере вы по-прежнему можете полагаться на свой механизм caching
, чтобы не поражать свой сервер каждый раз, возвращая кэшированные данные в виде файла Observable
. К счастью, RxJS предоставляет множество возможностей для создания Observables
, так что это не должно быть слишком сложным!
Краткий пример:
getCreditorsFromAPI(): Observable<Creditor[]> {
return this.http.get<Creditor[]>(this.creditorsUrl)
.pipe(
tap(data => this.creditorsCache = data)
)
);
}
getCreds(): Observable<Creditor[]> {
// You could also use this to invalidate your cache after 10 minutes!
if(this.creditorsCache.length > 0) {
return of(this.creditorsCache)
}
// Because I set the return type of this function, you will need to return a valid Observable. This makes your code predictable!
return this.getCreditorsFromAPI() // This will recreate your cache cause of the tap()!
}
В приведенном выше примере вы должны вызывать только service.getCreds()
и управлять подпиской в своем компоненте. Он будет кэшироваться для вас автоматически каждый раз, когда вы переназначаете свой наблюдаемый объект на this.service.getCreds()
.
Пища для размышлений! Я бы не сказал, что есть идеальный способ делать вещи, и определенно есть больше способов, которые ведут к фигуративному Риму; но то, что я только что описал, определенно немного больше Reactive
, на что Angular опирается во многих своих внутренних компонентах.
person
Bjorn 'Bjeaurn' S
schedule
04.06.2019
this.http.get<Creditor[]>(this.creditorsUrl)
и подписавшись вне службы. - person FrV   schedule 04.06.2019GET
вызывается для каждого компонента, который использует этот сервис, и я думаю, что это будет проблемой производительности, потому что я хочу иметь около 10 вкладок с компонент каждый. - person kkaragki   schedule 04.06.2019