将 *ngFor 与迭代器一起使用的正确方法是啥?

Posted

技术标签:

【中文标题】将 *ngFor 与迭代器一起使用的正确方法是啥?【英文标题】:What is the correct way of using *ngFor with an iterator?将 *ngFor 与迭代器一起使用的正确方法是什么? 【发布时间】:2018-05-23 18:59:16 【问题描述】:

TL;DR: 当使用带有 ngFor 的迭代器时,Angular 会引发 ExpressionChangedAfterItHasBeenCheckedError


我有一个使用ngFor 的模板,例如:

<div *ngFor="let something of foobarIterator()">

TypeScript 代码如下:

private foobar = [];

public foobarIterator() 
    return this.foobar[Symbol.iterator]();

根据 Angular 文档,允许将迭代器传递给 ngForOf 并且它确实可以工作……除了它之后会抛出一个 ExpressionChangedAfterItHasBeenCheckedError

虽然我知道这可能是因为每次调用该方法时我都会返回一个新的迭代器实例,但我并没有得到 Angular 所期望的。在迭代器用尽后使用相同的迭代器实例是没有意义的——毕竟它是一个迭代器,而不是数组本身。

那么在ngFor 中使用迭代器的正确方法是什么?

【问题讨论】:

【参考方案1】:

这个问题已经discussed 和solutions proposed 多次出现了.. 虽然不太容易找到。

Angular 6.1.0 最终提供了一个新的管道keyvalue (API docs),可以像这样在对象和地图上使用:

@Component(
  selector: 'keyvalue-pipe',
  template: `<span>
    <p>Object</p>
    <div *ngFor="let item of object | keyvalue">
      item.key:item.value
    </div>
    <p>Map</p>
    <div *ngFor="let item of map | keyvalue">
      item.key:item.value
    </div>
  </span>`
)
export class KeyValuePipeComponent 
  object: [key: number]: string = 2: 'foo', 1: 'bar';
  map = new Map([[2, 'foo'], [1, 'bar']]);

【讨论】:

这是另一个问题的答案!原始问题仍然是个大问题。

以上是关于将 *ngFor 与迭代器一起使用的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

将 cProfile 与 asyncio 代码一起使用的正确方法是啥?

将 NUMBERFMT 与 GetNumberFormatEx 一起使用的正确方法是啥?

将 Firebase 身份验证与 Firestore 一起使用的正确方法是啥?

将 Ionic Native / Cordova 插件与 Ionic (React) & Capacitor 一起使用的正确方法是啥?

使用着色器绘制 3D 对象的正确方法是啥?

将 SWIG 与 C++ 的 std::map 一起使用时,Java 没有迭代器