Angular 6-HttpClient保持订阅服务,但将结果传递给组件 [英] Angular 6 - HttpClient Keeping subscribe in the service but passing the result to the component
问题描述
我有一个预言,其中包含一个服务(获取数据)和一个组件(显示它).
I have a preject which contains a service (which gets the data) and a component (displays it).
我希望将app.component.ts上的代码保持在最低限度.
I would like the keep the code to the minimum on the app.component.ts.
在服务中,我有:
getPosts() {
return this.http.get('https://jsonplaceholder.typicode.com/posts', httpOptions).subscribe(
result => {
return result;
this.theData = result;
},
error => {
return error;
}
);
}
以及在我的app.component.ts中:
and in my app.component.ts:
getPostsFromService() {
this.myService.getPosts();
}
但是,当然,我需要获取结果并将其传递到我的组件中,但这样的操作不起作用:
But of course, I need to get the result and pass it into my component but something like this wouldn't work:
myData;
...
getPostsFromService() {
this.myData = this.myService.getPosts();
}
所以,我的问题是,我该怎么做?还是真的建议在我的组件上而不是在服务中调用订阅?
So, my question is, how can I do this or is it really recommended to call subscribe on my component and not in the service?
推荐答案
在新的 ="a href =" https://angular.io/guide/http"rel =" noreferrer> HttpClientModule 中是JSON的默认值,不再需要使用res.json()
您可以告诉HttpClient
响应的类型,以使使用输出变得更加容易和明显.
You can tell HttpClient
the type of the response to make consuming the output easier and more obvious.
可以使用类型参数来完成响应的类型检查
创建一个界面
Type checking of response can be done by using the type parameter
Create an Interface
export interface Idata{
userId:number;
Id:number;
title:string;
body:string;
}
Http
返回一个observable
,我们可以告诉HttpClient.get
作为Idata类型返回response
当我们使用http.get<Idata[]>(...)
时,它将返回Observable<Idata[]>
类型的实例.
为您提供服务
Http
returns an observable
and We can tell the HttpClient.get
to return response
as Idata type When we use http.get<Idata[]>(...)
then it returns the instance of Observable<Idata[]>
type.
In your service
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
至Observable<Idata[]>
中获取Idata的实例
In your component subscribe
to Observable<Idata[]>
to get instance of Idata
public data:Array<Idata>=[];
constructor(public service:ShareService)
{
this.service.getPosts().subscribe(value => {
this.data=value;
});
}
一种替代方法是使用async
管道
AsyncPipe
接受observable
或promise
作为参数,调用subscribe
或附加一个then处理程序,然后等待异步结果,然后再将其传递给调用方.
An alternative is Using async
pipe
AsyncPipe
accepts as an argument an observable
or a promise
, calls subscribe
or attaches a then handler, then waits for the asynchronous result before passing it through to the caller.
public response:Observable<Idata[]>;
constructor(public service:ShareService)
{
this.response=this.service.getPosts();
}
HTML
<div *ngFor="let item of (response|async)">
{{item.body}}
</div>
LIVEDEMO
我的问题是,我该怎么办?还是真的建议致电 订阅我的组件而不参与服务?
my question is, how can I do this or is it really recommended to call subscribe on my component and not in the service?
It's Good Practice to Delegate complex component logic to services
摘自 Angular样式指南
将组件中的逻辑限制为仅 视图所需的内容.所有其他逻辑应委托给 服务.
From Angular Style Guide
Do limit logic in a component to only that required for the view. All other logic should be delegated to services.
将可重用逻辑移至服务,并保持组件简单和 专注于他们的预期目的.
Do move reusable logic to services and keep components simple and focused on their intended purpose.
为什么?当放置在一个组件中时,逻辑可以被多个组件重用. 服务并通过功能公开.
Why? Logic may be reused by multiple components when placed within a service and exposed via a function.
为什么?可以在单元测试中更轻松地隔离服务中的逻辑, 而组件中的调用逻辑可以轻松模拟.
Why? Logic in a service can more easily be isolated in a unit test, while the calling logic in the component can be easily mocked.
为什么?删除依赖项并从中隐藏实现细节 组件.
Why? Removes dependencies and hides implementation details from the component.
为什么?使组件保持苗条,修剪和集中.
Why? Keeps the component slim, trim, and focused.
通过
订阅Component,您可以与多个observers
共享一个http
请求,否则,您将违反 分享
运算符.
Subscribing in Component lets you share a single http
request with multiple observers
, if you don't do so you would be violating DRY Principle
P:S
To share a single http
request for multiple observers
, you need something like the share
operator.
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$
}
}
此运算符是
publish
的特化形式,它创建了一个 当观察者的数量从零变为一时订阅,然后 与所有后续观察者共享该订阅,直到 观察者数量返回零,此时订阅 被处置.
This operator is a specialization of
publish
which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.
这篇关于Angular 6-HttpClient保持订阅服务,但将结果传递给组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!