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

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

问题描述

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

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

在组件subscribeObservable<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接受observablepromise作为参数,调用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


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

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