
本文详解如何使用 angular 内置的 `keyvaluepipe` 遍历任意 json 对象(非数组),在 html 模板中以 `
在 Angular 中,*ngFor 默认仅支持可迭代对象(如数组),但 JSON 对象本身不可直接遍历。幸运的是,Angular 提供了内置管道 KeyValuePipe(自 v6.1 起可用),它能将对象自动转换为 {key: string, value: any}[] 形式的数组,从而完美适配 *ngFor。
✅ 正确的数据结构准备(TypeScript 层)
关键前提是:确保组件 TS 文件中定义的属性名与模板中引用的名称完全一致,且结构扁平化。避免多层嵌套导致路径错误。
根据你的 Handlebars 模板逻辑,应将数据简化为:
// 在组件类中(例如 email-preview.component.ts)
export class EmailPreviewComponent implements OnInit {
Previous: Record = {};
Current: Record = {};
ngOnInit() {
// 假设你已通过服务或输入获取到 formData
const formData = {
Message_Body: {
formChanges: {
Previous: { Events: 'TEST', AdditionalInfo: '' },
Current: { Events: 'TEST111', AdditionalInfo: 'test' }
}
}
};
this.Previous = formData.Message_Body.formChanges.Previous;
this.Current = formData.Message_Body.formChanges.Current;
}
} ⚠️ 注意:原代码中 templateInput = { Message_Body: { Previous, Current } } 会导致模板需写成 Message_Body.Message_Body.Previous —— 这是常见错误根源。务必解构赋值为顶层属性(如 Previous / Current),提升可读性与健壮性。
✅ HTML 模板:用 | keyvalue 管道遍历对象
在 .html 文件中,直接使用 *ngFor + keyvalue 管道即可:
Title: This following has been changed!
Previous Values
0; else noPrev">
- {{ item.key }}: {{ item.value === '' || item.value == null ? '(empty)' : item.value }}
No previous values.
Current Values
0; else noCurr">
- {{ item.key }}: {{ item.value === '' || item.value == null ? '(empty)' : item.value }}
No current values.
✅ 效果输出:
Title: This following has been changed! Previous Values • Events: TEST • AdditionalInfo: (empty) Current Values • Events: TEST111 • AdditionalInfo: test
? 补充说明与最佳实践
-
keyvalue 管道默认按插入顺序排序(Angular ≥ 12),如需按字母序排列键,可传入比较函数:
compareKeys = (a: KeyValue
, b: KeyValue ) => a.key.localeCompare(b.key); 空值/undefined 安全处理:模板中使用 item.value === '' 显式判断空字符串(HTML 渲染时 {{ '' }} 会留白,建议统一提示为 (empty) 或 -)。
性能提示:keyvalue 管道在每次变更检测时会创建新数组。若对象极大(>100 键),建议在组件中预处理为数组并 OnPush 策略优化。
替代方案(不推荐):手动在 TS 中 Object.entries(obj) 转数组 → 更冗余,失去模板声明式优势;keyvalue 是 Angular 官方推荐的标准解法。
掌握 | keyvalue,你就能优雅、简洁、可维护地渲染任意结构化 JSON 数据——无论是配置项、表单快照,还是审计日志中的字段变更对比。










