如何在--prod模式下修复ngFor list问题?

时间:2019-05-08 21:23:45

标签: angular ngfor

我正在我的有角度的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模式下不会出现

2 个答案:

答案 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

有关