Angular 6 - HttpClient 保持订阅服务但将结果传递给组件 [英] Angular 6 - HttpClient Keeping subscribe in the service but passing the result to the component

查看:14
本文介绍了Angular 6 - HttpClient 保持订阅服务但将结果传递给组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个项目,其中包含一个服务(获取数据)和一个组件(显示数据).

我希望将 app.component.ts 上的代码保持在最低限度.

在我拥有的服务中:

getPosts() {返回 this.http.get('https://jsonplaceholder.typicode.com/posts', httpOptions).subscribe(结果 =>{返回结果;this.theData = 结果;},错误 =>{返回错误;});}

在我的 app.component.ts 中:

 getPostsFromService() {this.myService.getPosts();}

当然,我需要获取结果并将其传递到我的组件中,但是这样的事情是行不通的:

myData;...getPostsFromService() {this.myData = this.myService.getPosts();}

所以,我的问题是,我该怎么做,还是真的建议在我的组件上而不是在服务中调用订阅?

解决方案

在新的 HttpClientModule JSON 是假定的默认值,不再需要使用 res.json()

显式解析

您可以告诉 HttpClient 响应的类型,以便更轻松、更明显地使用输出.

响应的类型检查可以通过使用类型参数来完成
创建接口

导出接口 Idata{用户 ID:号码;身份证号码;标题:字符串;身体:字符串;}

Http 返回一个 observable 并且我们可以告诉 HttpClient.get 返回 response 作为 Idata 类型当我们使用 http.get(...) 然后它返回 Observable 类型的实例.
为您服务

import { Injectable } from '@angular/core';从'@angular/common/http' 导入 { HttpClient };从 'rxjs' 导入 {Observable};从 './Idata' 导入 {Idata}@Injectable()导出类 ShareService {构造函数(私有 httpc:HttpClient){}public getPosts():Observable{return this.httpc.get<Idata[]>('https://jsonplaceholder.typicode.com/posts');}}

在你的组件中subscribeObservable来获取Idata的实例

 公共数据:Array=[];构造函数(公共服务:共享服务){this.service.getPosts().subscribe(value => {this.data=值;});}

另一种方法是使用 async 管道AsyncPipe 接受 observablepromise 作为参数,调用 subscribe 或附加 then 处理程序,然后等待传递给调用者之前的异步结果.

公开回应:Observable;构造函数(公共服务:共享服务){this.response=this.service.getPosts();}

HTML

{{item.body}}


现场演示

<块引用>

我的问题是,我该怎么做,还是真的建议打电话订阅我的组件而不是服务?

将复杂的组件逻辑委托给服务

<块引用>

来自 Angular 样式指南
将组件中的逻辑限制为仅视图所需的.所有其他逻辑都应委托给服务.

务必将可重用逻辑移至服务并保持组件简单和专注于他们的预期目的.

为什么?当放置在一个组件中时,逻辑可以被多个组件重用服务并通过函数公开.

为什么?服务中的逻辑可以更容易地在单元测试中隔离,而组件中的调用逻辑可以轻松模拟.

为什么?删除依赖项并隐藏实现细节组件.

为什么?使组件保持苗条、修剪和集中.

订阅组件允许您与多个观察者共享单个http请求,否则将违反DRY 原则
P:S要为多个 observers 共享一个 http 请求,您需要类似于 share操作员.

从'rxjs'导入{Observable};从 'rxjs/operators' 导入 {share}导出类数据服务{公共数据$=Observable构造函数(http:HttpClient){this.data$=this.http.get('https://jsonplaceholder.typicode.com/posts').pipe(share());}public getPosts():Observable{返回 this.data$}}

<块引用>

这个操作符是 publish 的特化,它创建一个当观察者的数量从 0 变为 1 时订阅,然后与所有后续观察者共享该订阅,直到观察者数量归零,此时订阅已处理.

I have a project which contains a service (which gets the data) and a component (displays it).

I would like the keep the code to the minimum on the app.component.ts.

In the service I have:

getPosts() {
    return this.http.get('https://jsonplaceholder.typicode.com/posts', httpOptions).subscribe(
      result => {
        return result;
        this.theData = result;
      },
      error => {
        return error;
      }
    );
  }

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?

解决方案

In new HttpClientModule JSON is an assumed default and no longer needs to be explicitly parsed using res.json()

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 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');
    }
}

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;
     });
  }

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

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.

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$
    }
}

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆