英文:
When I add new element to the array, new cost in cont registered
问题
我正在学习Angular,遇到了第一个问题。我的服务看起来像这样:
import { Injectable } from '@angular/core';
import { COSTInterface } from './COSTSInterface';
import { Costs } from './mock-cost';
import { Observable, of } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class CostService {
getCosts(): Observable<COSTInterface[]> {
return of(Costs);
}
getBalance(): Observable<number> {
let balance = 0;
this.getCosts().subscribe(costs => {
for (const cost of costs) {
if (cost.type === 'income') {
balance += cost.cost;
} else {
balance -= cost.cost;
}
}
});
return of(balance)
}
add(element: COSTInterface): void {
Costs.push(element)
}
getCount(): Observable<number> {
return of(Costs.length);
}
constructor() { }
}
好的,我可以将新元素添加到数组中:
profileForm = this.fb.group({
id: [0],
name: [''],
type: [''],
cost: [0]
})
count: number = 0;
getCount() {
this.costService.getCount().subscribe(count => {
this.count = count + 1;
})
}
onSubmit() {
const newCost: COSTInterface = {
id: this.count || 0, // 如果值为null或undefined,则将0设置为默认值
name: this.profileForm?.value.name || '',
type: this.profileForm?.value.type || '',
cost: this.profileForm?.value.cost || 0
};
this.costService.add(newCost)
}
constructor(private fb: FormBuilder, private costService: CostService) { }
ngOnInit() {
this.getCount();
}
但是,在添加新元素后余额不会自动计算。
当我有余额时,摘要组件非常简单,看起来像这样:
balance: number = 0;
getBalance(): void {
this.costService.getBalance().subscribe(balance => {
this.balance = balance;
});
}
constructor(private costService: CostService) { }
ngOnInit() {
this.getBalance();
}
我可以猜到问题出在哪里,但我不知道如何解决它。可能是服务的getBalance方法不知道我们更改了成本数组,但我不知道如何解决这个问题。
在我添加新元素后,如何显示新的总成本?
英文:
I learning Angular and I have first problem. My service look like this
import { Injectable } from '@angular/core';
import { COSTInterface } from './COSTSInterface'
import {Costs} from './mock-cost'
import { Observable, of } from 'rxjs'
@Injectable({
providedIn: 'root'
})
export class CostService {
getCosts(): Observable<COSTInterface[]> {
return of(Costs);
}
getBalance(): Observable<number> {
let balance = 0;
this.getCosts().subscribe(costs => {
for (const cost of costs) {
if (cost.type === 'income') {
balance += cost.cost;
} else {
balance -= cost.cost;
}
}
});
return of(balance)
}
add(element: COSTInterface): void {
Costs.push(element)
}
getCount(): Observable<number>{
return of(Costs.length);
}
constructor() { }
}
OK. I can add new element to the array
profileForm = this.fb.group({
id: [0],
name: [''],
type: [''],
cost: [0]
})
count:number = 0;
getCount() {
this.costService.getCount().subscribe(count => {
this.count = count + 1;
})
}
onSubmit() {
const newCost: COSTInterface = {
id: this.count || 0, // Jeśli wartość jest null lub undefined, ustawiamy 0 jako domyślną wartość
name: this.profileForm?.value.name || '',
type: this.profileForm?.value.type || '',
cost: this.profileForm?.value.cost || 0
};
this.costService.add(newCost)
}
constructor(private fb: FormBuilder, private costService: CostService){}
ngOnInit(){
this.getCount();
}
But the balance is not calculated automatically when a new element is added.
Summary Component when I have the balance is very simple and looks like this
balance:number = 0;
getBalance(): void {
this.costService.getBalance().subscribe(balance => {
this.balance = balance;
});
}
constructor(private costService: CostService){}
ngOnInit() {
this.getBalance();
}
can guess where the problem is, but I have no idea how to solve it. Propably service's method getBalance don't know that we change array of costs but I don't know how solve this problem.
How can I display new total cost after I add new element?
答案1
得分: 0
Your CostService.getBalance is not handling asynchronous events properly. Rewrite it this way:
getBalance(): Observable
return this.getCosts()
.pipe(map(costs => {
let balance = 0;
for (const cost of costs) {
if (cost.type === 'income') {
balance += cost.cost;
} else {
balance -= cost.cost;
}
}
return balance;
}));
}
It makes the "getBalance" return the correct balance amount. But it wouldn't retrigger when a new cost is added. For this, you need BehaviorSubjects:
private balance$: BehaviorSubject
constructor(/someStuff/) {
// init balance
this.updateBalance();
}
getBalance(): Observable
return this.balance$.asObservable();
}
private updateBalance() {
this.getCosts()
.subscribe(costs => {
let balance = 0;
for (const cost of costs) {
if (cost.type === 'income') {
balance += cost.cost;
} else {
balance -= cost.cost;
}
}
// triggers the event to all subscribers
this.balance$.next(balance);
});
}
add(element: COSTInterface): void {
Costs.push(element);
this.updateBalance();
}
<details>
<summary>英文:</summary>
Your CostService.getBalance is not handling asynchronous events properly. Rewrite it this way:
getBalance(): Observable<number> {
return this.getCosts()
.pipe(map(costs => {
let balance = 0;
for (const cost of costs) {
if (cost.type === 'income') {
balance += cost.cost;
} else {
balance -= cost.cost;
}
}
return balance;
}));
}
It makes the "getBalance" return the correct balance amount. But it wouldn't retrigger when a new cost is added. For this, you need BehaviorSubjects:
private balance$: BehaviorSubject<number> = new BehaviorSubject(0); // 0 is default value)
constructor(/someStuff/) {
// init balance
this.updateBalance();
}
getBalance(): Observable<number> {
return this.balance$.asObservable();
}
private updateBalance() {
this.getCosts()
.subscribe(costs => {
let balance = 0;
for (const cost of costs) {
if (cost.type === 'income') {
balance += cost.cost;
} else {
balance -= cost.cost;
}
}
// triggers the event to all subscribers
this.balance$.next(balance);
}));
}
add(element: COSTInterface): void {
Costs.push(element);
this.updateBalance();
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论