当我向数组添加新元素时,新的成本在 `cont` 中注册。

huangapple go评论103阅读模式
英文:

When I add new element to the array, new cost in cont registered

问题

我正在学习Angular,遇到了第一个问题。我的服务看起来像这样:

  1. import { Injectable } from '@angular/core';
  2. import { COSTInterface } from './COSTSInterface';
  3. import { Costs } from './mock-cost';
  4. import { Observable, of } from 'rxjs';
  5. @Injectable({
  6. providedIn: 'root'
  7. })
  8. export class CostService {
  9. getCosts(): Observable<COSTInterface[]> {
  10. return of(Costs);
  11. }
  12. getBalance(): Observable<number> {
  13. let balance = 0;
  14. this.getCosts().subscribe(costs => {
  15. for (const cost of costs) {
  16. if (cost.type === 'income') {
  17. balance += cost.cost;
  18. } else {
  19. balance -= cost.cost;
  20. }
  21. }
  22. });
  23. return of(balance)
  24. }
  25. add(element: COSTInterface): void {
  26. Costs.push(element)
  27. }
  28. getCount(): Observable<number> {
  29. return of(Costs.length);
  30. }
  31. constructor() { }
  32. }

好的,我可以将新元素添加到数组中:

  1. profileForm = this.fb.group({
  2. id: [0],
  3. name: [''],
  4. type: [''],
  5. cost: [0]
  6. })
  7. count: number = 0;
  8. getCount() {
  9. this.costService.getCount().subscribe(count => {
  10. this.count = count + 1;
  11. })
  12. }
  13. onSubmit() {
  14. const newCost: COSTInterface = {
  15. id: this.count || 0, // 如果值为null或undefined,则将0设置为默认值
  16. name: this.profileForm?.value.name || '',
  17. type: this.profileForm?.value.type || '',
  18. cost: this.profileForm?.value.cost || 0
  19. };
  20. this.costService.add(newCost)
  21. }
  22. constructor(private fb: FormBuilder, private costService: CostService) { }
  23. ngOnInit() {
  24. this.getCount();
  25. }

但是,在添加新元素后余额不会自动计算。

当我有余额时,摘要组件非常简单,看起来像这样:

  1. balance: number = 0;
  2. getBalance(): void {
  3. this.costService.getBalance().subscribe(balance => {
  4. this.balance = balance;
  5. });
  6. }
  7. constructor(private costService: CostService) { }
  8. ngOnInit() {
  9. this.getBalance();
  10. }

我可以猜到问题出在哪里,但我不知道如何解决它。可能是服务的getBalance方法不知道我们更改了成本数组,但我不知道如何解决这个问题。

在我添加新元素后,如何显示新的总成本?

英文:

I learning Angular and I have first problem. My service look like this

  1. import { Injectable } from &#39;@angular/core&#39;;
  2. import { COSTInterface } from &#39;./COSTSInterface&#39;
  3. import {Costs} from &#39;./mock-cost&#39;
  4. import { Observable, of } from &#39;rxjs&#39;
  5. @Injectable({
  6. providedIn: &#39;root&#39;
  7. })
  8. export class CostService {
  9. getCosts(): Observable&lt;COSTInterface[]&gt; {
  10. return of(Costs);
  11. }
  12. getBalance(): Observable&lt;number&gt; {
  13. let balance = 0;
  14. this.getCosts().subscribe(costs =&gt; {
  15. for (const cost of costs) {
  16. if (cost.type === &#39;income&#39;) {
  17. balance += cost.cost;
  18. } else {
  19. balance -= cost.cost;
  20. }
  21. }
  22. });
  23. return of(balance)
  24. }
  25. add(element: COSTInterface): void {
  26. Costs.push(element)
  27. }
  28. getCount(): Observable&lt;number&gt;{
  29. return of(Costs.length);
  30. }
  31. constructor() { }
  32. }

OK. I can add new element to the array

  1. profileForm = this.fb.group({
  2. id: [0],
  3. name: [&#39;&#39;],
  4. type: [&#39;&#39;],
  5. cost: [0]
  6. })
  7. count:number = 0;
  8. getCount() {
  9. this.costService.getCount().subscribe(count =&gt; {
  10. this.count = count + 1;
  11. })
  12. }
  13. onSubmit() {
  14. const newCost: COSTInterface = {
  15. id: this.count || 0, // Jeśli wartość jest null lub undefined, ustawiamy 0 jako domyślną wartość
  16. name: this.profileForm?.value.name || &#39;&#39;,
  17. type: this.profileForm?.value.type || &#39;&#39;,
  18. cost: this.profileForm?.value.cost || 0
  19. };
  20. this.costService.add(newCost)
  21. }
  22. constructor(private fb: FormBuilder, private costService: CostService){}
  23. ngOnInit(){
  24. this.getCount();
  25. }

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

  1. balance:number = 0;
  2. getBalance(): void {
  3. this.costService.getBalance().subscribe(balance =&gt; {
  4. this.balance = balance;
  5. });
  6. }
  7. constructor(private costService: CostService){}
  8. ngOnInit() {
  9. this.getBalance();
  10. }

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

  1. 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;
}));
}

  1. 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 = new BehaviorSubject(0); // 0 is default value)
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();
}

  1. <details>
  2. <summary>英文:</summary>
  3. 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;
}));
}

  1. It makes the &quot;getBalance&quot; return the correct balance amount. But it wouldn&#39;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();
}

  1. </details>

huangapple
  • 本文由 发表于 2023年7月6日 20:01:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76628618.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定