我正在弄清楚 Angular 服务是如何工作的,但我不明白为什么 HeroCounter(数字)不能正确更新,而英雄数组却可以正确更新。例如,当我添加一个新的虚拟英雄时,我希望 HeroCounter 会增加。
如果您能帮助我,请先谢谢您。
英雄.services.ts
import { Injectable } from '@angular/core';
import { Hero } from '../model/hero.model';
import { HEROES } from '../constants/hero.constant';
import { Observable, of } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class HeroService {
heroes!: Hero[];
heroesCounter!:number;
constructor() {
this.heroes = HEROES;
this.heroesCounter = this.heroes.length;
}
getHeroes(): Observable<Hero[]> {
return of(this.heroes);
}
getHeroesCounter(): Observable<number> {
return of(this.heroesCounter);
}
mockAddHero(name: string): void {
setTimeout(() => {
this.heroes.push(new Hero(name));
this.heroesCounter = this.heroes.length;
console.log(this.heroesCounter);
}, 1500);
}
}
app.component.ts
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { HeroService } from '../services/hero.service';
import { Hero } from '../model/hero.model';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrl: './app.component.css',
})
export class AppComponent implements OnInit {
heroes!: Hero[];
heroesCounter!: number;
constructor(private heroService: HeroService) {}
getHeroes(): void {
this.heroService.getHeroes().subscribe((heroes) => (this.heroes = heroes));
}
getHeroesCounter(): void {
this.heroService
.getHeroesCounter()
.subscribe((counter) => {this.heroesCounter = counter});
}
ngOnInit(): void {
this.getHeroes();
this.getHeroesCounter();
}
addHero(): void {
this.heroService.mockedAddHero('new hero');
}
}
app.component.html
<div>
<button (click)="addHero()" >Add Dummy Hero</button>
<ul>
<!-- This works -->
@for(hero of heroes; track $index){
<li>{{hero.name}}</li>
}
</ul>
<!-- This does not work -->
<p> Total of heroes: {{this.heroesCounter}}</p>
</div>
从我从您的代码中收集到的信息,这是因为角度变化检测与内存引用(除其他外)一起工作:更新内存引用会触发变化检测。
这就是您的数组所发生的情况:您将一个新值设置到其内存引用中。
但是对于原始值(字符串、数字、布尔值)来说,它不起作用。
如果您希望使其正常工作,您应该使用
ChangeDetectorRef.detectChanges()
自行触发更改检测。
但更重要的是,我建议您首先了解有关可观察量及其工作原理的更多信息,特别是使用
async
管道:您的代码很容易出现此类问题,正确使用可观察量将防止大多数问题发生.
换句话说:这是您错误创建的边缘案例,不要在上面浪费太多时间并继续学习!