Angular:如何摆脱ExpressionChangedAfterItHaHasBeenCheckedError

时间:2019-07-16 13:39:13

标签: angular typescript

我有一个选框的小样本,它是由地图内容生成的。

https://stackblitz.com/edit/angular-mqccjn

课程

public map : Map <string, string> = new Map <string, string> ([
    [ "NEW", "?" ],
    [ "ACCEPTED", "&#10003;" ],
    [ "DECLINED", "&#10005;" ]
]);

组件

<select>
        <option *ngFor="let m of map.keys()" [innerHTML]="map.get(m)"></option>
</select>

我不知道为什么会收到此Java运行时异常。

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngForOf: [object Map Iterator]'. Current value: 'ngForOf: [object Map Iterator]'."

1 个答案:

答案 0 :(得分:2)

它将在每个循环上重新评估map.keys(),使它每次都获得一个新对象。您最好立即将其存储在这样的地方:

public map : Map <string, string> = new Map <string, string> ([
    [ "NEW", "?" ],
    [ "ACCEPTED", "&#10003;" ],
    [ "DECLINED", "&#10005;" ]
]);

public mapEntries = Array.from(this.map.entries());

和您的模板:

<select>
  <option *ngFor="let m of mapEntries" [value]="m[0]">{{m[1]}}</option>
</select>

另一种方法是保持其状态不变,并使用OnPush更改检测策略,出于性能考虑,建议始终这样做:

import { Component, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent  {}