我正在我的有角度的Web应用程序中遍历数组,该数组在firebase中进行更新,并直接从firebase中获取。它在开发模式下可以正确显示,但列表/索引仅在--prod
模式下与每个击键保持翻转和交换。
观看这段详细的视频here可以更清楚地显示问题,并比较使用--prod
和不使用--prod
的情况
服务代码:
getDonors(projectUrl: string) {
return this.db.collection(`Donors`, ref => ref.where('projectUrl', '==', projectUrl)).snapshotChanges().pipe(map(
snaps => {
const donors = snaps.map(
snap => {
return {
donorId: snap.payload.doc.id,
data: snap.payload.doc.data()
};
}
);
return donors;
}
));
}
组件代码:
ngOnInit() {
this.companyUrl = 'someName';
this.eventUrl = this.route.snapshot.params['eventUrl'];
this.projectUrl = this.route.snapshot.params['projectUrl'];
console.log(this.companyUrl + '-' + this.eventUrl + '-' + this.projectUrl);
this.services.getDonors(this.projectUrl).subscribe(
d => {
this.donorsList = d;
}
);
}
HTML代码
<ng-container *ngFor="let donor of donorsList.reverse()">
<div class="row">
<div class="col-md-4">
<p class="m-0">{{ donor.data.title }} / {{ donor.data.name }}</p>
</div>
<div class="col-md-3">
<p class="m-0">{{ donor.data.eventUrl }}</p>
</div>
<div class="col-md-3">
<p class="m-0">{{ donor.data.amount }} ريال</p>
</div>
<div class="col-md-1 text-center">
<button class="btn btn-success btn-sm" (click)="onEdit(donor.donorId)">تعديل</button>
</div>
<div class="col-md-1 text-center">
<button class="btn btn-danger btn-sm" (click)="onDelete(donor.donorId)">X</button>
</div>
<hr>
</div>
</ng-container>
此问题在development
模式下不会出现
答案 0 :(得分:1)
我的应用程序遇到类似的问题。
问题来自您HTML中的.reverse()
。
每次调用时(这意味着在每个事件上),都会发生反向更改,而对you数组进行修改。
这意味着从单击事件到从ajax调用接收到的数据之类的任何东西都会触发更改检测,然后调用donorsList.reverse()
。
您可以尝试将donorsList.reverse()
替换为donorsList.slice().reverse()
。因此,您将不会更改原始数组。
答案 1 :(得分:0)
首先,您可以将其编写为:
getDonors(projectUrl: string) {
return this.db.collection(`Donors`, ref => ref.where('projectUrl', '==', projectUrl)).snapshotChanges()
.pipe(
map(snaps => snaps.map(snap => ({
donorId: snap.payload.doc.id,
data: snap.payload.doc.data()
})
)
);
}
也不要在视图中放置reverse()
之类的逻辑。在ngOnInit中执行此操作:
this.services.getDonors(this.projectUrl)
.subscribe(d => this.donorsList = d.reverse());.
您的问题很可能是由于从数据源获取无序数据而引起的,除非默认情况下按快照顺序排序,否则每次更新数据时,它将以不同的顺序返回数据。尝试在查询中使用某种排序方式。
此外,要确保*ngFor
指令中的更新高效且一致,请使用trackBy
函数。
<ng-container *ngFor="let donor of donorsList; trackBy: trackByFn">
在您的课堂上:
trackByFn(index, element) {
return element.donorId;
}
--prod
标志没有引起问题的原因。使用*ngFor
的生产中有成千上万个角度应用程序。这与您的订购逻辑和缺少trackBy