Я пишу сервис на Angular. Объявите переменную в классе обслуживания:
private tariffCache: {id: number, observable: Observable<Tariff>}[] = [];
(внимание к идентификатору)
Заполните эту переменную в функции:
getTariff(id: number): Observable<Tariff> {
if (!this.tariffCache || !this.tariffCache.find(x => x.id === id)) {
const url = ${this.tariffsUrl}/${id};
this.tariffCache.push({
id,
observable: this.http.get<Tariff>(url, this.httpOptions)
.pipe(shareReplay(1))
});
}
return this.tariffCache.find(x => x.id === id).observable;
}
Что я ожидаю увидеть в переменной ' tarCache 'после ответа от сервера с id = 34?
{id: 34, observable: Observable}
Верно! Но на самом деле:
{id: "34", observable: Observable}
Ух ты? Почему 34 сейчас строка? Когда это преобразовать в строку ?! Но это еще не все! Я повторяю вызов этой функции с id = 34. 34 - это цифра c, иначе компилятор выдаст ошибку. Весь код в функции 'getTariff' работает! Функция 'find' отлично работает с оператором сравнения "===". Массив содержит объект со строковым идентификатором и находит элемент с числовым значением c id. Брррр ...
Я пишу другую функцию с тем же кодом с функцией 'найти', и она не работает. Какая? Почему не сейчас?
Хорошо, я изменил функцию getTariff на:
getTariff(id: number): Observable<Tariff> {
if (!this.tariffCache || !this.tariffCache.find(x => x.id === +id)) {
const url = ${this.tariffsUrl}/${id};
this.tariffCache.push({
id: +id,
observable: this.http.get<Tariff>(url, this.httpOptions)
.pipe(shareReplay(1))
});
}
return this.tariffCache.find(x => x.id === +id).observable;
}
И теперь массив содержит объект с цифрой c id, и другие функции также работают с массивом. Может ли кто-нибудь объяснить это поведение «id» и «find»? Спасибо.
UPD: вызов функции 'getTariff' из функции 'changeCurrentTariff' в службе. Функция clearTariff не работает до изменения getTariff. Это фрагмент кода в сервисе:
export class TariffService extends AbstractModelService {
private tariffsUrl = environment.baseUrl + 'api/Tariffs';
private tariffCache: {id: number, observable: Observable<Tariff>}[] = [];
private tariffSource = new BehaviorSubject<Tariff>(null);
constructor(private http: HttpClient) {
super();
}
currentTariff = this.tariffSource.asObservable();
changeCurrentTariff(id: number) {
if (id) {
this.getTariff(id)
.subscribe(tariff => {
this.tariffSource.next(tariff);
});
}
}
/** GET tariff by id. Will 404 if id not found */
getTariff(id: number): Observable<Tariff> {
if (!this.tariffCache || !this.tariffCache.find(x => x.id === +id)) {
const url = `${this.tariffsUrl}/${id}`;
this.tariffCache.push({
id: +id,
observable: this.http.get<Tariff>(url, this.httpOptions)
.pipe(shareReplay(1))
});
}
return this.tariffCache.find(x => x.id === +id).observable;
}
clearTariff(id: number) {
if (this.tariffCache) {
const index = this.tariffCache.findIndex(x => x.id === +id);
if (index >= 0) {
this.tariffCache.splice(index, 1);
}
}
}
}
Но вызов changeCurrentTariff из компонента:
export class TariffComponent implements OnInit, OnDestroy {
constructor(
private route: ActivatedRoute,
private tariffService: TariffService,
) { }
ngOnInit() {
this.route.params
.pipe(
takeUntil(this.unsubscribe)
)
.subscribe(params => {
if (params.id) {
this.tariffService.changeCurrentTariff(params.id);
}
});
}
}