#angular #typescript
#angular #typescript
Вопрос:
У меня есть service DisplaysService, в котором есть переменная moneys
. Когда я что-то покупаю с помощью компонента buy button
on the buy, я обновляю значение переменной в сервисе из компонента. Однако обновленное значение не отражается в компоненте sell, даже если я получаю значение из сервиса. Значение, отображаемое в компоненте sell, является исходным значением переменной в сервисе DisplaysService.
displays.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class DisplaysService {
moneys = 50000;
constructor() { }
}
buy.component.ts
import { DisplaysService } from './../displays.service';
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-buy',
templateUrl: './buy.component.html',
styleUrls: ['./buy.component.css']
})
export class BuyComponent implements OnInit {
moneys : number;
Response = {};
selectedcurrency : string = "Select Currency"
constructor(private http : HttpClient, private displaysservice : DisplaysService) { }
ngOnInit(): void {
this.http.get('https://api.coinranking.com/v1/public/coins?base=EURamp;timePeriod=7d')
.subscribe(Response => {
console.log(Response)
this.Response = Response
});
}
ChangeCurrencySymbol (newcurrency : string) {
this.selectedcurrency = newcurrency;
}
ChangeMoneys (moneysspent : Number) {
this.moneys = this.displaysservice.moneys - Number(moneysspent);
this.displaysservice.moneys = this.moneys;
}
}
sell.component.ts
import { DisplaysService } from './../displays.service';
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-sell',
templateUrl: './sell.component.html',
styleUrls: ['./sell.component.css']
})
export class SellComponent implements OnInit {
moneys : number;
Response = {};
selectedcurrency : string = "Select Currency"
constructor(private http : HttpClient, private displaysservice : DisplaysService) { }
ngOnInit(): void {
this.http.get('https://api.coinranking.com/v1/public/coins?base=EURamp;timePeriod=7d')
.subscribe(Response => {
console.log(Response)
this.Response = Response
});
}
ChangeCurrencySymbol (newcurrency : string) {
this.selectedcurrency = newcurrency;
}
ChangeMoneys (moneysspent : Number) {
this.moneys = this.displaysservice.moneys Number(moneysspent);
this.displaysservice.moneys = this.moneys;
}
}
Комментарии:
1. Пробовал извлекать значение в ngOnInit() ??
Ответ №1:
Проблема
Angular пытается оптимизировать производительность, применяя изменения к пользовательскому интерфейсу, когда ожидается, что изменение обновит пользовательский интерфейс.
Рассмотрим приведенную ниже последовательность событий
- Вы присваиваете свойству
DisplayService: moneys
значение 50,000.00 - Вы присваиваете свойству
BuyComponent: moneys
значениеDisplayService: moneys
, теперьBuyComponent: moneys
значение равно50,000
- Вы присваиваете свойству
SellComponent: moneys
значениеDisplayService: moneys
, теперьSellComponent: moneys
значение равно50,000
- Теперь давайте обновим
SellComponent: moneys
, а затем обновимDisplayService: moneys
- Теперь у нас проблема, компонент никак не
BuyComponent
мог знать об этом изменении
Решение
Простым подходом было бы установить значение DisplayService: moneys
как a BehaviorSubject
и подписаться на это как в компонентах Buy, так и в компонентах Sell . Таким образом, значение будет синхронизировано. Смотрите приведенный ниже код
displays.service.ts
private readonly initialMoneys = 50000;
moneysSubject$ = new BehaviorSubject(this.initialMoneys);
moneys$ = this.moneysSubject$.asObservable();
updateDisplay({ amount, type }) {
if (type === "sell") {
this.moneysSubject$.next(amount this.moneys);
}
if (type === "buy") {
this.moneysSubject$.next(-amount this.moneys);
}
}
get moneys() {
return this.moneysSubject$.value;
}
buy.component.ts
export class BuyComponent implements OnInit {
moneys$ = this.displaysservice.moneys$;
Response = {};
selectedcurrency: string = "Select Currency";
constructor(
private http: HttpClient,
private displaysservice: DisplaysService
) {}
ngOnInit(): void {
this.http
.get("https://api.coinranking.com/v1/public/coins?base=EURamp;timePeriod=7d")
.subscribe(Response => {
console.log(Response);
this.Response = Response;
});
}
ChangeCurrencySymbol(newcurrency: string) {
this.selectedcurrency = newcurrency;
}
ChangeMoneys(moneysspent: number) {
this.displaysservice.updateDisplay({ amount: moneysspent, type: "sell" });
}
}
sell.component.ts
export class SellComponent implements OnInit {
moneys$ = this.displaysservice.moneys$;
Response = {};
selectedcurrency: string = "Select Currency";
constructor(
private http: HttpClient,
private displaysservice: DisplaysService
) {}
ngOnInit(): void {
this.http
.get("https://api.coinranking.com/v1/public/coins?base=EURamp;timePeriod=7d")
.subscribe(Response => {
console.log(Response);
this.Response = Response;
});
}
ChangeCurrencySymbol(newcurrency: string) {
this.selectedcurrency = newcurrency;
}
ChangeMoneys(moneysspent: number) {
this.displaysservice.updateDisplay({amount: moneysspent, type:'buy'});
}
}