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

Ionic Angular中*ngFor遍历渲染卡片无内容显示问题

问题描述

调用Laravel开发的API接口可正常返回数据,Ionic项目中使用*ngFor循环渲染拉取的用户数据时页面无内容,移除*ngFor指令后静态示例卡片可正常展示。

相关代码

post-list 组件模板

<ion-list>
    <ion-list-header> Usuarios </ion-list-header>
    <app-post-item *ngFor=" let item of usaurios" [usuario]="item">
    </app-post-item>
</ion-list>

post-item 组件模板

<ion-item>
    <ion-avatar slot="start">
        <img src="https://i.pravatar.cc/150?img=2" />
    </ion-avatar>
    <ion-label>
        <h2>Finn</h2>
        <h3>I'm a big deal</h3>
        <p>Listen, I've had a pretty messed up day...</p>
    </ion-label>
</ion-item>

效果参考

  • 异常效果:异常效果截图
  • 移除*ngFor=" let item of usaurios" [usuario]="item"后正常效果:正常显示效果

user.service 服务代码

export class UserService {
    public url: String = environment.url;
    public usuarios$ = new Subject<Usuario[]>(); 
    public usuario$ = new Subject<Usuario>();

    public usuarios: Usuario[] = [];
    public usuario: Usuario;
    constructor(public http: HttpClient) {}
    all$(): Observable<Usuario[]> {
        return this.usuarios$.asObservable();
    }
    all(): Observable<any> {
        this.usuarios = [];
        return this.http.get<Usuario[]>(this.url + 'usuario').pipe(
            map ((res: any[]) => {
                Array.from(res).forEach((item: any) => {
                    this.usuario = new Usuario();
                    this.usuario.set(item);
                    this.usuarios.push(this.usuario);
                });
                this.usuarios$.next(this.usuarios);
                console.log(res);
            })
        );
    }
}

post-list.component.ts 组件代码

export class PostListComponent implements OnInit {
    public usaurios: Usuario[] = [];
    public usuario: Usuario;
    public usuarioSubscription = new Subscription();

    constructor(
        public userservice: UserService
    ) {}

    ngOnInit() {
        this.usuarioSubscription = this.userservice.all$().subscribe((res: Usuario[])=>{
            this.usaurios = res;
        });
        this.userservice.all().subscribe(res => {
            console.log('Listo...');
        });
    }
}

控制台输出

控制台截图

post-item.component.ts 组件代码

import { Component, Input, OnInit } from '@angular/core';
import { Usuario } from 'src/app/models/usuario';

@Component({
    selector: 'app-post-item',
    templateUrl: './post-item.component.html',
    styleUrls: ['./post-item.component.scss'],
})
export class PostItemComponent implements OnInit {
    @Input() usuario: Usuario;
    constructor() {}

    ngOnInit() {}
}
问题原因与修复方案

核心问题共3处:

  1. RxJSmap操作符使用错误:pipe(map())必须返回处理后的结果,当前代码中map回调无返回值,导致流发射值为undefined,状态逻辑耦合在map回调中极易出现不一致问题。
  2. 冗余状态设计:服务层额外维护内部数组+Subject双层状态,多余的中间层容易出现订阅时序、状态重置导致的空值问题。
  3. 资源泄漏风险:组件中订阅观察对象后未在销毁阶段取消订阅,长期运行会出现内存泄漏。
  4. 额外问题:post-item模板为全静态内容,未使用传入的usuario输入属性,即使循环成功也会渲染出完全一致的静态卡片。

修复步骤

  1. 简化服务层逻辑,移除冗余的Subject和内部状态维护,直接返回转换后的用户数组:
// user.service.ts 修正后
export class UserService {
    public url: String = environment.url;
    constructor(public http: HttpClient) {}

    all(): Observable<Usuario[]> {
        return this.http.get<any[]>(this.url + 'usuario').pipe(
            map ((res: any[]) => {
                return res.map(item => {
                    const usuario = new Usuario();
                    usuario.set(item);
                    return usuario;
                })
            })
        );
    }
}
  1. 简化组件逻辑,直接订阅HTTP请求返回的观察对象,补充销毁阶段的取消订阅逻辑,修正变量拼写错误(原变量usaurios为拼写错误,正确拼写为usuarios):
// post-list.component.ts 修正后
export class PostListComponent implements OnInit, OnDestroy {
    public usuarios: Usuario[] = [];
    private usuarioSubscription = new Subscription();

    constructor(public userservice: UserService) {}

    ngOnInit() {
        this.usuarioSubscription = this.userservice.all().subscribe((res: Usuario[])=>{
            this.usuarios = res;
        });
    }

    ngOnDestroy() {
        this.usuarioSubscription.unsubscribe();
    }
}
  1. 同步修正模板中的循环变量名:
<!-- post-list 组件模板修正后 -->
<ion-list>
    <ion-list-header> Usuarios </ion-list-header>
    <app-post-item *ngFor="let item of usuarios" [usuario]="item">
    </app-post-item>
</ion-list>
  1. 修改post-item组件模板,将静态内容替换为usuario属性对应的字段,比如:
<ion-item>
    <ion-avatar slot="start">
        <img src="https://i.pravatar.cc/150?img=2" />
    </ion-avatar>
    <ion-label>
        <h2>{{usuario.name}}</h2>
        <h3>{{usuario.title}}</h3>
        <p>{{usuario.description}}</p>
    </ion-label>
</ion-item>

若修正后仍不渲染,优先检查控制台是否有组件未声明、路由配置错误类的报错,移除*ngFor时单个组件可正常显示说明组件本身声明无问题,90%以上场景为数据流逻辑导致的数组为空问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:57:26