【问题标题】:Angular not updating part of view角度不更新视图的一部分
【发布时间】:2018-03-29 02:39:18
【问题描述】:

我有一个组件,我在其中显示一些图表,旁边有一个表格,显示每个图表的最新值。

我正在为数组中的每个对象执行此操作,如下所示:

<div class="patient-box level-2" *ngFor="let bed of patientService.bedsLevel2" draggable="true" (dragstart)="onDrag($event, bed)">
...
<table class="vsTable">
    <tr>
      <th [matTooltip]="translations?.Tooltip.Type">Type</th>
      <th [matTooltip]="translations?.Tooltip.AverageReading1624">16-24t</th>
      <th [matTooltip]="translations?.Tooltip.Chart" translate>Chart</th>
      <th [matTooltip]="translations?.Tooltip.AverageReading01">0-1t</th>
    </tr>
    <tr *ngFor="let vitalSign of vitalSigns; let i = index">
      <td [matTooltip]="getTooltip(vitalSign)">{{vitalSign}}</td>
      <td>{{getVitalSign(bed.timeWindows[5], vitalSign)}}</td>
      <td>
        <chart [options]="lineChartOptions" (load)="saveLineChart($event.context, vitalSign, bed)" draggable="true"></chart>
      </td>
      <td>{{getVitalSign(bed.timeWindows[0], vitalSign)}}</td>
    </tr>
  </table>

我时不时地调用服务器来更新patientService.bedsLevel2 数组:

updateBeds() {
this.patientService.bedsLevel2.forEach(bed => {
  this.patientService.getBedDetails(bed.cetreaName).subscribe(
    (result: BedDetails) => {
      this.updateChartData(result);
      bed = result;
    },
    err => {
      console.log(err);
    }
  );
});
this.updateBedsTimeout = setTimeout(() => this.updateBeds(), BED_UPDATE_INTERVAL);

}

正如您在代码中看到的,我使用结果来更新图表数据,然后将其作为新值分配给bed 对象。此方法完成后,图表的视图已经更新,但旁边的表格中的数据没有更新。

我了解到 Angular 不会检测到更改,除非对数组的引用发生更改,因此我尝试将以下各项添加到 updateBeds() 方法的末尾:

this.patientService.bedsLevel2 = [...this.patientService.bedsLevel2];
this.patientService.bedsLevel2 = this.patientService.bedsLevel2.slice();

但他们都没有解决问题。什么可能导致这个问题,为什么我尝试修复它不起作用,以及什么会解决它?我已经阅读了一些关于使用 ChangeDetectorRef 手动进行更改检测的内容,所以我可能会尝试一下。

【问题讨论】:

  • 你不只是改变局部变量的值而不是数组中的值吗? bed = result 只是将 bed 局部变量的指针更改为指向您的新结果。这不会改变数组中的引用。
  • @DanielWSrimpel 我正在做一个forEach 的数组,其中bed 代表每个对象。
  • 是的,但是bed 是一个变量,它指向你在内存中的对象。当您为该变量重新分配一个值时,您只是更改了该局部变量指向的内容......这对数组中的值没有影响。

标签: angular


【解决方案1】:

您错误地更改了本地 bed 变量的值。请查看下面的代码并运行以查看仅将本地引用更改为指向新对象实际上不会更改数组中的值。如果要更改整个对象引用,则必须按索引更改原始数组中的引用(如下所示)。

let beds = [
  { cetreaName: 'Bed #1' },
  { cetreaName: 'Bed #2' },
  { cetreaName: 'Bed #3' }
];

console.log('before', JSON.stringify(beds));

beds.forEach(bed => {
  bed = { cetreaName: 'Updated ' + bed.cetreaName };
});

console.log('after (not updating)', JSON.stringify(beds));

beds.forEach((bed, index) => {
  beds[index] = { cetreaName: 'Updated ' + bed.cetreaName };
});

console.log('after (updating)', JSON.stringify(beds));

【讨论】:

  • 我明白了,谢谢。我认为forEach 会给我一个对数组中实际对象的引用,并可以为它们分配新值。如果我将得到的所有结果添加到一个新数组中,然后在最后写入 patientServive.bedsLevel2 = new array with objects from server call 会怎样?
  • forEach 确实为您提供了对该实际对象的引用。如果您更改该对象的属性,则在使用该对象的任何地方都可以看到该属性。但是,更改变量指向的对象对它指向的原始对象没有任何作用。但是,是的,解决您的问题的最佳方法可能是批量处理您的请求并将您的数组设置为该新数组,以确保 Angular 在您的模板中重新处理它。 RxJS 有方法等待 Observable 集合完成(例如 Observable.forkJoin)。
猜你喜欢
  • 2015-01-07
  • 1970-01-01
  • 2020-12-17
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 2016-10-23
  • 1970-01-01
  • 2018-04-02
相关资源
最近更新 更多