Ваш статический массив не может быть вне области вашего сервиса. Тем не менее, вы не можете иметь 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 для большинства своих внутренних компонентов.