Я пробую Ionic и хотел сделать конвертер валют на практике. Приложение извлекает некоторые данные из API Rest, а затем во внешнем интерфейсе используется для расчета обменного курса определенной суммы денег. Я хочу, чтобы он работал так же, как работает preev.com.
У меня есть служба, которая получает данные из API Rest и принимает два параметра, которые являются валютами для конвертации. Затем служба отправляет запрос на получение в нужную конечную точку в зависимости от параметров / валют.
На моей странице у меня есть функция, которая отправляет параметры / валюты службе, а затем подписывается на нее.
В этой части у меня две проблемы:
Во-первых, потому что это наблюдаемое, оно слишком часто обновляется. Я попытался решить эту проблему, отправляя интервальный запрос на сервер каждые 60 секунд, но это не сработало, а другой способ, которым я пытался решить эту проблему, заключался в попытке получить значение один раз из компонента перед подпиской с помощью метода first().
Когда я переключаюсь между валютами в моем выбранном компоненте, targetAmount мигает между текущей обменной стоимостью и прошлой обменной стоимостью. Например, валюты по умолчанию для обмена в моем приложении - BTC / CLP, но когда я выбираю BTC / COP, он мигает двумя курсами обмена в течение нескольких секунд, пока не покажет текущий обменный курс, который я собираюсь использовать. Наконец, когда я переключаюсь между валютами, не дожидаясь отображения только текущего обмена, происходит сбой.
Вот мой код:
Страница:
export class Page {
baseCurrency = 'BTC';
targetCurrency = 'CLP';
baseAmount = 1;
exchangeRate: number;
subscription;
constructor(public navCtrl: NavController,
private exchangeService: ExchangeService) {
}
supportedCurrencies = ['BTC', 'ETH', 'BCH'];
supportedCurrencies2 = ['CLP', 'COP', 'PEN'];
get targetAmount() {
this.subscription = this.exchangeService.getBudaFiat(this.baseCurrency, this.targetCurrency)
.first()
.subscribe(
val => {
this.exchangeRate = val.ticker.last_price[0];
}
)
return this.baseAmount * this.exchangeRate;
}
ionViewWillLeave() {
this.subscription.unsubscribe();
console.info("SALIO");
}
}
HTML:
<ion-content>
<ion-list>
<input type = "number" [(ngModel)] = "baseAmount"
[class.error] = "isInvalid(baseAmount)">
<currency-select [(selected)] = "baseCurrency"></currency-select>
= <strong>{{targetAmount}}</strong>
<currency-select2 [(selected)] = "targetCurrency"></currency-select2>
<p *ngIf = "isInvalid(baseAmount)">Please enter a valid amount</p>
</ion-list>
</ion-content>
Услуга:
getBudaFiat(baseCurrency: string, targetCurrency: string) {
return Observable.interval(60000)
.startWith(0)
.switchMap(() => {
return this.http.get(`https://wt-e2369b36b992e69ccc8f05d9b48dd8e2-0.sandbox.auth0-extend.com/cryptoalarma/${baseCurrency}${targetCurrency}`)
.map((response: Response) => response);
});
}
Код также доступен на Stackblitz, и вы можете проверить проблему на вкладке «Контакт»:
Ссылка на приложение Stackblitz
Спасибо за вашу помощь!
Обновлено:
Извините, я забыл упомянуть, что во второй проблеме, которую я объяснил, он начинает использовать много памяти, пока приложение не зависает.
@Antoniossss, извини, я исправил.





Вам необходимо правильно импортировать подписку:
import {Subscription} from 'rxjs/Subscription';
а затем введите переменную подписки:
subscription: Subscription;
и наконец
this.subscription.unsubscribe();
Последняя часть самая важная.
Если вы попытаетесь отказаться от подписки, для которой не введена подписка, подписка не будет отменена. Это также должно дать вам ошибку линтинга.
Привет, Сандра, спасибо за помощь, но это не работает. Он отписывается, когда я покидаю страницу, но у меня все еще есть основные проблемы. Если я переключаюсь между валютами, он начинает использовать много памяти и мигает обменные курсы. Вы можете проверить это здесь: stackblitz.com/edit/ionic-yljfbt?file=pages%2Fabout%2Fabout. ts Ваше решение реализовано на вкладке «О программе».
Обычно это происходит из-за того, что вы отказались от подписки, но ваша тема все еще отправляет ...
Я использую этот способ, который очень удобен, и вам не нужно создавать переменные для каждой подписки.
alive со значением по умолчанию true.takeWhile(() => this.alive) перед subscribeOnDestroyalive значение false на ngOnDestroyтогда автоматически он отменит подписку, наблюдаемую, когда ваш компонент будет уничтожен
export class MyComponent implements OnDestroy, OnInit {
public user: User;
private alive: boolean = true;
public ngOnInit() {
this.userService.authenticate(email, password)
.takeWhile(() => this.alive)
.subscribe(user => {
this.user = user;
});
this.otherService.getdata()
.takeWhile(() => this.alive)
.subscribe(data => {
});
}
public ngOnDestroy() {
this.alive = false;
}
}
Вы можете прочитать больше в здесь
Привет, Реза Рахмати, спасибо за помощь, но это не работает. Он по-прежнему использует много памяти, а также отображает курсы обмена валют. Вы можете проверить это здесь: stackblitz.com/edit/… Ваше решение реализовано на вкладке «Контакты».
@ ClaudioRamírezGuichard, вы не реализовали OnDestroy и ngOnDestroy, чтобы установить alive на false
Сделал, просто после того, как не вышло, попробовал с ionViewWillLeave(). В любом случае, в той ссылке, которую вы мне дали, она все еще мигает среди обменных курсов, когда вы переключаете валюты, в которые нужно конвертировать. Кстати, я только что понял, что http тоже не работает и начинает показывать много ошибок в консоли. Когда это происходит, утечки памяти увеличиваются.
@ ClaudioRamírezGuichard Проблема с вашим кодом заключается в том, что вы подписываетесь на get targetAmount, что означает, что каждый раз, когда вызывается свойство get, вы подписываетесь снова, вместо этого лучше иметь обработчик событий для изменения валюты, вызывать свой api с помощью first () или take (1) и сохраните общую сумму в переменной.
Где эта утечка памяти указана в заголовке ??