【问题标题】:Send data from service to observable Get request将数据从服务发送到可观察的 Get 请求
【发布时间】:2020-05-25 02:29:06
【问题描述】:

我是 Angular 和 Observables 的新手。我有一个服务,它接收我想要传递给我的 observable 的 URL,并在每次使用 NgFor 将新 URL 传递给它时呈现数据。任何例子都会有所帮助。请帮助似乎没有任何工作。提前致谢

服务文件

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Event } from '../event/event.interface';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})

export class ClientService {

  eventUrl ;

  constructor(private http: HttpClient) {
  }

 receiveEvent(eventId){
    this.eventUrl = eventId;
   console.log(this.eventUrl)
 }

renderEvent(eventUrl): Observable<Event[]>{
  return this.http
  .get<Event[]>(eventUrl)
}

接收组件文件

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ClientService } from '../service/clientService';
import { HttpParams, HttpClient } from '@angular/common/http';


@Component({
  selector: 'hero-review',
  templateUrl: './review.component.html',
  styleUrls: ['./review.component.css']
})
export class ReviewComponent implements OnInit {

public events = [];

  constructor(private _clientService: ClientService) { 
  }

  ngOnInit() {

    this._clientService.renderEvent('Need to be dynamic URL').subscribe(data => this.events = data);
  }
}

发送组件文件

sendEvent(eventId){
  let reqUrl = "myEndpoint" + eventId;
  this._clientService.receiveEvent(reqUrl);
}

【问题讨论】:

  • 这在语法上看起来不错。您能否提供更多有关您正在努力解决的特定领域的信息,包括您迄今为止尝试过的示例。
  • 嗨,Kurt,我更新了示例。发送文件将 url 发送到服务。服务需要将其传递给发出 GET 请求的 Observable。每次传递 URL 时,我都希望 Observable 呈现请求的数据
  • 我仍然不明白什么在这里不起作用。接收组件是否在发送组件更新服务中的 url 后的某个时间点加载?
  • Observable 在传递给服务时没有接收到动态 URL。我不确定它在哪里失败。每次发送 URL 时,我都希望更新它
  • 我尝试了您的示例,但无法确定主题类型是什么。需要导入吗?

标签: angular observable angular-services ngfor get-request


【解决方案1】:

我想我理解你的问题。

http.get(url) 是一次性的 observable。它不是像主题那样可以多次触发的流。您需要创建自己的主题并将其用作代理。

export class ClientService {

 constructor(private http: HttpClient) {
 }

 private eventPublisher: Subject<Event[]> = new Subject<Event[]>();

 receiveEvent(eventId){
   // call http client here, and publish results to event publisher
   const eventUrl = eventId;
   this.http.get<Event[]>(eventUrl).subscribe(response => {
     this.eventPublisher.next(response);
   });
 }

 renderEvent(eventUrl): Observable<Event[]>{
  // do not subscribe to http client here, subscribe to event publisher
  return this.eventPublisher.asObservable();
 }

这是发布-订阅设计模式(发布者 - 订阅者)。阅读其他使用 Angular 的设计模式的解决方案可能会很有用,因为这是一个相当简单的示例。

编辑:

完成订阅后,您还需要取消订阅组件以避免内存泄漏。

这是一个简单的模式:

export class MyComponent implements OnInit, OnDestroy() {
  constructor(private myService: MyService) { }

  private destroyed: Subject<void> = new Subject<void>();

  ngOnInit(): void {
    this.myService.myMethod().pipe(
      takeUntil(() => this.destroyed)
    ).subscribe(() => { 
      // do stuff
    });
  }

  ngOnDestroy(): void {
    this.destroyed.next(undefined);
    this.destroyed.complete();
  }
}

虽然如果您需要开始做很多事情,它确实会重复。我个人使用这个方法:https://stackoverflow.com/a/45709120/5367916

【讨论】:

  • myService 没有myMethod
  • 这只是模式的伪代码演示,而不是实际的实现。
【解决方案2】:
// This sample using angular 9/10
// Component name:  list.component.ts

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { NgZone} from '@angular/core';
import {HttpServiceService} from './../http-service.service';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.scss']
})
export class ListComponent implements OnInit {

  constructor(
     private http: HttpServiceService,
     private zone: NgZone
    ) { }
  brews: object;
  ngOnInit(): void {
      this.http.getPeople().subscribe(data => {
      this.brews = data;
      alert(JSON.stringify(this.brews));
      console.log(this.brews);
      });
  }
}
//--------------------------------

// This is my http service
// Component Name: http-service.service.ts

import { Observable, of } from 'rxjs';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class HttpServiceService {

  constructor() { }
  getPeople(): Observable<any>{
    const myNameArray = [{
      firstName: 'Algem',
      lastName: 'Mojedo',
      age: 63
    }];
    return of(myNameArray);
 }
}

//--------------------------
// should display in alert

localhost:4200 says
[{"firstName":"Algem","lastName":"Mojedo","age":"60"}]

Happy coding..

【讨论】:

    猜你喜欢
    • 2014-01-28
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 2017-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多