Angular 6 HttpClient调用JSONPlaceholder接口,模板无法显示响应数据
问题分析与解决方案
我一眼就看出问题所在了——你处理API响应的方式不对!
核心问题
当你调用https://jsonplaceholder.typicode.com/posts时,这个接口返回的是一个包含多个post对象的数组,但你在组件里做了这样的操作:
this.vals = [data];
这就把原本的posts数组又包了一层,变成了[ [post1, post2, ...] ]这种二维数组。*ngFor遍历这个二维数组时,每个item其实是整个posts数组,自然没有title属性,所以模板显示不出内容。
而调用/posts/1时,接口返回的是单个post对象,[data]就变成了包含单个对象的一维数组,*ngFor能正常遍历并读取item.title,所以能显示。
修正步骤
1. 调整接口定义
首先,你的接口应该定义单个post的结构,因为API返回的是多个该类型的对象数组,还要注意数据类型匹配(JSONPlaceholder返回的userId和id是数字,不是字符串):
export interface Post { userId: number; id: number; title: string; body?: string; // 可选,如果你需要显示正文的话 }
2. 优化服务代码(Angular最佳实践)
你的服务现在只返回URL,建议把HTTP请求逻辑放在服务里,这样组件更简洁,也方便复用:
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { Post } from './post.interface'; // 替换成你的接口实际路径 @Injectable({ providedIn: 'root' }) export class PostsService { private _url = 'https://jsonplaceholder.typicode.com/posts'; constructor(private http: HttpClient) { } // 获取所有posts getPosts(): Observable<Post[]> { return this.http.get<Post[]>(this._url); } // 获取单个post(可选,方便后续扩展) getSinglePost(id: number): Observable<Post> { return this.http.get<Post>(`${this._url}/${id}`); } }
3. 修正组件代码
在组件里直接订阅服务返回的数组,不需要额外包装:
import { Component, OnInit } from '@angular/core'; import { PostsService } from './posts.service'; // 替换成你的服务实际路径 import { Post } from './post.interface'; @Component({ selector: 'app-posts', templateUrl: './posts.component.html', styleUrls: ['./posts.component.css'] }) export class PostsComponent implements OnInit { vals: Post[] = []; // 初始化为空数组,避免模板报错 constructor(private api: PostsService) { } ngOnInit(): void { this.api.getPosts().subscribe(data => { this.vals = data; // 直接把返回的数组赋值给vals }); } }
4. 模板保持不变
你的模板代码是正确的,现在vals是一维数组,*ngFor能正常遍历每个post对象:
<li *ngFor="let item of vals"> {{item.title}} </li>
额外优化建议
- 可以使用
async管道来订阅Observable,这样不需要手动管理订阅,代码更简洁:
组件对应代码调整:<li *ngFor="let item of vals$ | async"> {{item.title}} </li>vals$: Observable<Post[]>; ngOnInit(): void { this.vals$ = this.api.getPosts(); }
内容的提问来源于stack exchange,提问作者RRB
相关产品推荐
相关产品推荐

