You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至Angular 7后原Angular 6代码失效致浏览器无限加载原因咨询

Angular 7中*ngFor调用Object.keys导致无限加载的原因及解决办法

嘿,我之前升级Angular版本的时候也碰到过一模一样的问题!咱们来拆解一下原因和解决办法:

问题根源

在Angular 7中,变更检测机制的敏感度有所提升。你在模板里直接调用objectKeys(items),每次Angular执行变更检测时,这个方法都会返回一个新的数组引用(哪怕数组里的内容和之前完全一样)。Angular会把这个新数组判定为“数据发生了变化”,于是就会重新渲染这部分DOM,而重新渲染又会触发变更检测,反复循环下去,最终导致浏览器无限加载。

而Angular 6的变更检测逻辑没这么严格,对这种“引用变化但内容不变”的情况处理得更宽松,所以之前没触发这个问题。

解决办法

有两种常用的方案可以搞定这个问题:

方案1:提前计算并存储键数组

在组件初始化时就把items的键计算好,存在一个组件属性里,模板直接遍历这个属性即可:

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

@Component({
  selector: 'app-page',
  template: `<div *ngFor="let key of itemKeys">{{key + ' : ' + items[key]}}</div>`
})
export class MyComponent implements OnInit {
  items = { keyOne: 'value 1', keyTwo: 'value 2', keyThree: 'value 3' };
  itemKeys: string[];

  ngOnInit() {
    // 初始化时计算一次键数组
    this.itemKeys = Object.keys(this.items);
  }

  // 如果items后续会动态更新,记得在更新后重新计算键数组
  updateItems(newItems: object) {
    this.items = newItems;
    this.itemKeys = Object.keys(this.items);
  }
}

方案2:使用自定义纯管道

Angular的纯管道只会在输入值发生实际变化时才重新计算,所以可以写一个专门提取对象键的管道:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'keys' })
export class KeysPipe implements PipeTransform {
  transform(value: object): string[] {
    return value ? Object.keys(value) : [];
  }
}

记得在对应的模块里声明这个管道,然后模板里这样用:

<div *ngFor="let key of items | keys">{{key + ' : ' + items[key]}}</div>

这个方案更适合items会动态变化的场景,不用手动去更新键数组,管道会自动处理。

内容的提问来源于stack exchange,提问作者user3458271

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:24:08