如何正确输出一个detail post的模板?
How to output a template of detail post rightly?
我正在写学习项目Angular。我的项目显示 https://jsonplaceholder.typicode.com/ 中的 posts。我想显示详细的 post 模板(例如 localhost:3000/posts/1)。我在方法 getById 中的 posts.service.ts 处得到一个特定的 post。现在我有一个错误 - “类型 'Subscription' 与类型 'Post' 没有共同的属性”。但我不知道如何解决这个问题。我的错误在哪里?如何解决?如何正确输出模板({{ post.title }})?
此处所有项目:posts project
post.service.ts:
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
export interface Post {
title: string;
userId?: number;
}
@Injectable({ providedIn: "root" })
export class PostService {
private _postsURL = "https://jsonplaceholder.typicode.com";
constructor(private http: HttpClient) {}
public fetchPosts(page: number, itemsPerPage: number): Observable<Post[]> {
let posts = this.http.get<Post[]>(`${this._postsURL}/posts`);
return this.getPageItems(posts, page, itemsPerPage);
}
private getPageItems(
posts: Observable<Post[]>,
page: number,
itemsPerPage: number
): Observable<Post[]> {
return posts.pipe(
map((u) => {
let startIndex = itemsPerPage * (page - 1);
return u.slice(startIndex, startIndex + itemsPerPage);
})
);
}
getById(id: number) {
let post = this.http
.get<Post[]>(`${this._postsURL}/posts/${id}`)
.subscribe();
return post;
}
}
post.component.ts:
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute, Params } from "@angular/router";
import { Post, PostService } from "../post.service";
@Component({
selector: "app-post",
templateUrl: "./post.component.html"
})
export class PostComponent implements OnInit {
post: any;
constructor(
private route: ActivatedRoute,
private postsService: PostService
) {}
ngOnInit(): void {
this.route.params.subscribe((params: Params) => {
this.post = this.postsService.getById(+params.id);
});
}
}
post.component.html:
<div>
post component
<h1>{{ post.title }}</h1>
</div>
您可以更改代码中的多项内容以完成这项工作并遵循最佳做法。
当组件被销毁时,异步管道还将负责取消订阅可观察对象,因此您不必手动取消订阅它。
它在变化检测方面也更有效。
在你 post.service 中将 getById 更改为 return observable:
另外,如果您想查看结构化的 HTML json 响应,您可以使用“
”标签。
getById(id: number): Observable<Post> {
return this.http.get<Post>(`${this._postsURL}/posts/${id}`);
}
和post.component.html到:
<div>
post component
<h1>{{ (post | async )?.title }}</h1>
<pre>{{ (post | async) }}</pre> // you can see structured json
</div>
请检查固定样本:
https://codesandbox.io/s/trusting-drake-zgri7?file=/src/app/post/post.component.ts
有多种方法可以解决这个问题。我会提出以下解决方案:
在服务中,您可以return observable。在这里,您将 return 类型转换为 Observable 以 returning 订阅。所以将其更改为:此外,它是 returning 单个 Post 而不是 Post[]。请验证。
getById(id: number): Observable<Post> {
let post = this.http.get<Post>(`${this._postsURL}/posts/${id}`);
return post;
}
在 html 中,您可以使用异步管道获取标题的值:
<h1>{{ (post | async)?.title }}</h1>
我正在写学习项目Angular。我的项目显示 https://jsonplaceholder.typicode.com/ 中的 posts。我想显示详细的 post 模板(例如 localhost:3000/posts/1)。我在方法 getById 中的 posts.service.ts 处得到一个特定的 post。现在我有一个错误 - “类型 'Subscription' 与类型 'Post' 没有共同的属性”。但我不知道如何解决这个问题。我的错误在哪里?如何解决?如何正确输出模板({{ post.title }})?
此处所有项目:posts project
post.service.ts:
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
export interface Post {
title: string;
userId?: number;
}
@Injectable({ providedIn: "root" })
export class PostService {
private _postsURL = "https://jsonplaceholder.typicode.com";
constructor(private http: HttpClient) {}
public fetchPosts(page: number, itemsPerPage: number): Observable<Post[]> {
let posts = this.http.get<Post[]>(`${this._postsURL}/posts`);
return this.getPageItems(posts, page, itemsPerPage);
}
private getPageItems(
posts: Observable<Post[]>,
page: number,
itemsPerPage: number
): Observable<Post[]> {
return posts.pipe(
map((u) => {
let startIndex = itemsPerPage * (page - 1);
return u.slice(startIndex, startIndex + itemsPerPage);
})
);
}
getById(id: number) {
let post = this.http
.get<Post[]>(`${this._postsURL}/posts/${id}`)
.subscribe();
return post;
}
}
post.component.ts:
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute, Params } from "@angular/router";
import { Post, PostService } from "../post.service";
@Component({
selector: "app-post",
templateUrl: "./post.component.html"
})
export class PostComponent implements OnInit {
post: any;
constructor(
private route: ActivatedRoute,
private postsService: PostService
) {}
ngOnInit(): void {
this.route.params.subscribe((params: Params) => {
this.post = this.postsService.getById(+params.id);
});
}
}
post.component.html:
<div>
post component
<h1>{{ post.title }}</h1>
</div>
您可以更改代码中的多项内容以完成这项工作并遵循最佳做法。 当组件被销毁时,异步管道还将负责取消订阅可观察对象,因此您不必手动取消订阅它。
它在变化检测方面也更有效。
在你 post.service 中将 getById 更改为 return observable:
另外,如果您想查看结构化的 HTML json 响应,您可以使用“
”标签。getById(id: number): Observable<Post> {
return this.http.get<Post>(`${this._postsURL}/posts/${id}`);
}
和post.component.html到:
<div>
post component
<h1>{{ (post | async )?.title }}</h1>
<pre>{{ (post | async) }}</pre> // you can see structured json
</div>
请检查固定样本:
https://codesandbox.io/s/trusting-drake-zgri7?file=/src/app/post/post.component.ts
有多种方法可以解决这个问题。我会提出以下解决方案:
在服务中,您可以return observable。在这里,您将 return 类型转换为 Observable 以 returning 订阅。所以将其更改为:此外,它是 returning 单个 Post 而不是 Post[]。请验证。
getById(id: number): Observable<Post> {
let post = this.http.get<Post>(`${this._postsURL}/posts/${id}`);
return post;
}
在 html 中,您可以使用异步管道获取标题的值:
<h1>{{ (post | async)?.title }}</h1>