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

如何访问JSON嵌套对象属性值并解决Angular嵌套ngFor渲染报错

问题修复方案

问题根因

  • 方案1报错的核心原因是Fragment模型中verses属性的类型定义错误,你定义的是单个Verse对象,但实际业务中一个片段对应多个经文,应该是Verse[]数组类型,*ngFor只能遍历可迭代的集合,不能遍历单个对象。
  • 方案2报错是因为你在同步代码中直接操作未初始化的fragments、verses变量,且逻辑混乱,异步请求返回前这两个变量都是undefined,自然会报属性缺失错误。

修复步骤

1. 修正Fragment模型类型定义

修改fragments.ts中的verses属性类型,同时补充嵌套经文的反序列化逻辑:

import {Deserializable} from './deserializable';
import { Chapter } from './chapter';
import { Verse } from './verse';

export class Fragment implements Deserializable {
    public id?: number;
    public url?: string;
    public surtitle?: string;
    public title_string?: string;
    public title_format?: number;
    public verses?: Verse[]; // 把原来的Verse改为Verse[]
    public chapter_id?: Chapter;

  deserialize(input: any): this {
      Object.assign(this, input);
      // 对嵌套的经文列表做实例化反序列化
      if (input.verses) {
        this.verses = input.verses.map(verseItem => new Verse().deserialize(verseItem));
      }
      return this;
    }
}

2. 修正组件逻辑

删除ngOnInit中多余的同步map处理代码,直接使用Observable配合async管道即可,不需要手动维护本地变量,避免异步时序问题:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import {map} from 'rxjs/operators';
import { Fragment } from '../models/fragment';
import {ResponseApi} from '../models/api';
import { FragmentService } from '../services/fragment.service';


@Component({
  selector: 'app-livre-detail',
  templateUrl: './livre-detail.component.html',
  styleUrls: ['./livre-detail.component.scss']
})
export class LivreDetailComponent implements OnInit {

  fragments$!: Observable<Fragment[]>;

  constructor(
    private route: ActivatedRoute,
    private fragmentService: FragmentService,  
  ) { }

  ngOnInit() {
        const routeParams = this.route.snapshot.paramMap;
        const bookDiminutiveFromRoute = String(routeParams.get('bookDiminutive'));
    
        this.fragments$ = this.fragmentService.filterList(
          'chapter_id__book_id__diminutive', bookDiminutiveFromRoute).pipe(
          map((responseApi: ResponseApi<Fragment>) => {
            // 对返回的每个片段做反序列化实例化
            return responseApi.results.map(fragmentItem => new Fragment().deserialize(fragmentItem));
          })
        );
  }
}

3. 修正模板代码

配合async管道遍历,同时添加空值保护避免属性为空时报错:

<div *ngFor= 'let fragment of fragments$ | async'>
  <h3>{{ fragment.title_string }}</h3>
    <div>
      <!-- ?? [] 做空值兜底,经文列表为空时不会触发遍历错误 -->
      <div *ngFor= 'let verse of fragment.verses ?? []'>
        <span>{{ verse.number }}. </span>
        <span>{{ verse.text }}</span>
    </div>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:06:03