我有一个preject包含一个服务(获取数据)和一个组件(显示它)。
我想在app.component.ts上将代码保持在最低限度。
在我的服务中:
:-1: error: An exception was triggered:
Exception at 0x4015f6, code: 0x4000001f: Win32 x86 emulation subsystem breakpoint hit, flags=0x0.
并在我的app.component.ts中:
getPosts() {
return this.http.get('https://jsonplaceholder.typicode.com/posts', httpOptions).subscribe(
result => {
return result;
this.theData = result;
},
error => {
return error;
}
);
}
但是,当然,我需要得到结果并将其传递给我的组件,但这样的事情不会起作用:
getPostsFromService() {
this.myService.getPosts();
}
所以,我的问题是,我该怎么做呢?或者是否真的建议在我的组件上调用subscribe而不是在服务中?
答案 0 :(得分:4)
在新的 HttpClientModule 中,JSON是假设的默认值,不再需要使用res.json()
显式解析
您可以告诉HttpClient
响应的类型,使输出更容易,更明显。
可以使用类型参数
来完成响应的类型检查
创建一个接口
export interface Idata{
userId:number;
Id:number;
title:string;
body:string;
}
Http
返回observable
我们可以告诉HttpClient.get
将response
作为Idata类型返回当我们使用http.get<Idata[]>(...)
时,它会返回{的实例{1}}类型。
在您的服务中
Observable<Idata[]>
在您的组件import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {Observable} from 'rxjs';
import {Idata} from './Idata'
@Injectable()
export class ShareService {
constructor(private httpc:HttpClient)
{
}
public getPosts():Observable<Idata[]>
{
return this.httpc.get<Idata[]>('https://jsonplaceholder.typicode.com/posts');
}
}
至subscribe
中获取Idata的实例
Observable<Idata[]>
另一种方法是使用 public data:Array<Idata>=[];
constructor(public service:ShareService)
{
this.service.getPosts().subscribe(value => {
this.data=value;
});
}
管道
async
接受AsyncPipe
或observable
作为参数,调用promise
或附加一个then处理程序,然后在将其传递给调用者之前等待异步结果。< / p>
subscribe
<强> HTML 强>
public response:Observable<Idata[]>;
constructor(public service:ShareService)
{
this.response=this.service.getPosts();
}
的 LIVEDEMO 强>
我的问题是,我该怎么做或者是否真的建议打电话 订阅我的组件而不是服务?
<强> It's Good Practice to Delegate complex component logic to services 强>
来自 Angular样式指南
仅限制组件中的逻辑 视图所需的。应该委托所有其他逻辑 服务。将可重用逻辑移动到服务并保持组件简单 专注于他们的预期目的。
为什么呢?放置在a中时,逻辑可以被多个组件重用 服务并通过功能公开。
为什么呢?服务中的逻辑可以更容易地在单元测试中被隔离, 而组件中的调用逻辑很容易被模拟。
为什么呢?删除依赖项并隐藏实现细节 成分
为什么呢?保持组件纤薄,修剪和聚焦。
订阅组件可让您与多个<div *ngFor="let item of (response|async)">
{{item.body}}
</div>
共享一个http
请求,如果您不这样做,则会违反 DRY Principle
<强>点:S 强>
要为多个observers
分享单个http
请求,您需要 share 之类的内容
操作
observers
此运算符是
import {Observable} from 'rxjs'; import {share} from 'rxjs/operators' export class dataService { public data$=Observable<Idata[]> constructor(http:HttpClient) { this.data$=this.http.get<Idata[]>('https://jsonplaceholder.typicode.com/posts').pipe(share()); } public getPosts():Observable<Idata[]> { return this.data$ } }
的特化,它创建了一个 当观察者的数量从零变为1时的订阅 与所有后续观察者共享该订阅,直至该订阅 观察者数量返回零,此时订阅 处置。
答案 1 :(得分:1)
大!您可以尝试使用Observable和Async! 在app.component
中public posts: Observable<posts[]>
getPostsFromService() {
this.posts = this.myService.getPosts();
}
在html中,你说的是:
*ngFor="let post of posts | async"
服务
return this._http.get<posts>('https://jsonplaceholder.typicode.com/posts', httpOptions)
试试看看是否有效!我希望有所帮助!
答案 2 :(得分:0)
如果您希望使用服务方法,必须返回如下的可观察响应:
public getPosts(): Observable<IPosts[]> {
const data = {
'$type' : 'ReadRequest',
'query' : 'getPosts',
'parameters' : {}
};
return this.http.post(null, data)
.map(res => (<any>res)._body === '' ? {} : res.json().result)
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
return Promise.reject(error.message || 'Server error: ' + error);
}
描述IPosts
的位置根据您的回复进行接口。
在任何组件之后,你可以使用它:
public posts: IPosts[] = [];
this.servicePosts.getPosts().subscribe(data => {
this.posts = data; // Fill data from response to component variable this.post
}, error => {
console.log(error);
});
答案 3 :(得分:-1)
你的component.ts应该是这样的。
您的服务没有问题,除了订阅应该是地图。
this.myService.getPosts().subscribe((data) => {
this.setMyData(data);
});
setMyData() {
this.myData = data;
}