javascript - 当我更新数据库时,为什么我的所有组件都会重新渲染?
我正在尝试在 Firebase RTDB 中更新一个值,并意识到当我这样做时,所有连接到该可观察对象的组件都会被重新加载,这是为什么?
TS
import { Component, OnChanges, OnInit, SimpleChanges, Inject } from '@angular/core';
import { AngularFireDatabase } from '@angular/fire/compat/database';
import { BehaviorSubject, Observable, switchMap } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
squad = new Array;
timeline$: Observable<any[]>;
lineup$: Observable<any[]>;
x$ = new BehaviorSubject<string>('first_race');
constructor(private db: AngularFireDatabase) {
// Get Lineups
this.lineup$ = this.x$.pipe(switchMap((x) => {
return this.db.list('lineups/'+x).valueChanges();
}))
// Get Timeline
this.timeline$ = this.x$.pipe(switchMap((x$) => {
return this.db.list(x$).valueChanges();
}))
}
match_no(b: string) {
this.x$.next(b);
}
changer(){
this.lineup$.subscribe({next:(value: any[]) => this.squad.push(value[0])});
console.log(this.squad[0])
}
}
HTML
<div *ngFor="let lines of lineup$ | async">
<ng-container *ngIf="lines.lineups != undefined">
<button type="button" (click)='match_no("first_race")' (click)='changer()'>Game 1</button>
<div *ngFor="let tl of lineup$ | async">
<p *ngFor="let starting_lineup of tl.lineups[0].starting_lineup">{{ starting_lineup.name}}</p>
</div>
</ng-container>
</div>
数据看起来是这样的
JSON
"lineups":{
"first_race":[
{
"lineups":[{
"starting_lineup":[
{
"name": "Racer 1",
"position": "1",
"car": "fast_bigwheel_car"
},
{
"name": "Racer 3",
"position": "2",
"car": "fast_flying_car"
},
{
"name": "Racer 2",
"position": "3",
"car": "fast_small_car"
}
]
}]
}]
}
如果我要去 Racer 2 并将 "car" 从 "fast_small_car" 改成其他东西,那么整个应用程序会刷新。我认为这可能与 <ng-container *ngIf="lines.lineups != undefined"> 有关,但我需要它,因为有时它会回来为空,然后应用程序就无法正常渲染。
帮帮我!!!
答案#1
尝试使用trackBy,这样*ngFor就知道哪些元素需要刷新,哪些不需要刷新,这可能解决你的问题!
<div *ngFor="let lines of lineup$ | async; trackBy: trackByIndex">
<ng-container *ngIf="lines.lineups != undefined">
<button type="button" (click)='match_no("first_race")' (click)='changer()'>Game 1</button>
<div *ngFor="let tl of lineup$ | async; trackBy: trackByIndex">
<p *ngFor="let starting_lineup of tl.lineups[0].starting_lineup; trackBy: trackById">{{ starting_lineup.name}}</p>
</div>
</ng-container>
</div>
这些功能将会是
trackByIndex(index: number) {
return index;
}
trackById(_index: number, item: any) {
return item.id;
}
