我该如何从角度组件侦听服务中的http调用?

时间:2019-07-15 06:40:25

标签: angular typescript asynchronous

我只是从angular开始,我需要一些有关侦听组件中服务中新的http调用的帮助。最初,我使用content.component.ts通过fetch-article.service从ngOnInit通过api调用获取数据(返回数组) 之后,当另一个组件(sidebar.component.ts)调用updateID时,它将从fetch-article.service调用相同的函数。我想做的是从fetch-article.service发出新的http请求后,items中的content.component.ts变量应该具有新获取的数据的值。

content.component.ts:

export class ContentComponent implements OnInit {
  items = [];

  constructor(
    private fetchArticlesService: FetchArticlesService) {}

  ngOnInit() {
    this.getArticlesbyID('123')
    .subscribe(result => {
     console.log('test')
  });

  getArticlesbyID(id){
  return this.fetchArticlesService.fetchArticles(id).pipe(map(
    fetchArticlesService => {
      this.items = Object(fetchArticlesService);
    })
  )}
}

在我的fetch-article.service.ts中,我有:

export class FetchArticlesService {

  fetchArticles(id) {
    return this.http.get('http://127.0.0.1:5000/query/' + id);
  }

  constructor(
    private http: HttpClient
  ) { }
}

sidebar.component.ts:

updateID(id) {
    this.fetchArticlesService.fetchArticles(id)
  }

请帮助我。我刚开始使用Angular。 Stackblitz代码:https://stackblitz.com/edit/angular-vyotee

3 个答案:

答案 0 :(得分:4)

对HTTP模块的订阅意味着,一旦获得响应,订阅将默认完成并被销毁。因此,您当前的逻辑将永远无法工作。我看到的另一个问题是在这里

updateID(id) {
    this.fetchArticlesService.fetchArticles(id)
  }
  

要执行您创建的可观察对象并开始接收   通知时,您调用它的subscription()方法,并传递一个观察者。

换句话说,此方法将永远不会触发,因为需要订阅可观察到的才能触发它。进一步了解here

您的问题的解决方案是创建另一个可观察的对象(Subject),然后订阅该对象:

export class FetchArticlesService {
  public articles: Subject<any> = new Subject();

  constructor(
    private http: HttpClient
  ) { }

  fetchArticles(id) {
    return this.http.get('http://127.0.0.1:5000/query/' + id).pipe(
      map((result) => {
         this.articles.next(result);
      }));
  }

}

现在要在组件中调用API并使用新数据加载刚刚创建的观察者,您必须执行以下操作:

this.fetchArticlesService.fetchArticles(id).subscribe();

content.component.ts或任何其他组件中,您必须订阅articles。这样,您可以自动“更新”多个位置的响应数据。

this.fetchArticlesService.articles.subscribe((res) => console.log(res));

在此处检查解决方案: https://stackblitz.com/edit/angular-edotfc

重要提示:每当您“杀死”具有该订阅的组件时,停止订阅以防止内存泄漏也很重要。但是,如果您的组件一直处于活动状态(例如导航栏,边栏和该类型的组件),则无需这样做。最好的方法是在ngOnDestroy

内销毁它
ngOnDestroy() {
  this.fetchArticlesService.articles.unsubscribe();
}

答案 1 :(得分:1)

您是否已按角度介绍了主题?我认为这是主题的理想案例。

对象本身是可观察的,但使它们与众不同的是它们也是观察者。这意味着什么?这意味着除了具有订阅功能之外,主题还可以发出数据。

(在fetch-article-service中)定义主题:let fetchSubject= new Subject<string>();

发射数据(从侧边栏传递ID):fetchSubject.next("Eureka");

订阅主题更改:fetchSubject.subscribe((data) => { console.log("Subscriber got data >>>>> "+ data); });

根据收到的ID,您可以在那里进行http调用。结果可以传递给主题,该主题将传递给所有订户。对于这种特殊情况,您可能需要对流程进行一些操作。

我可以看到的大致流程是,您可以使用subject.next在主题中传递http调用的结果。主题中的数据一旦更改,它将通知新数据到您可能要使用的任何地方。希望这对您有用。

答案 2 :(得分:1)

看看这张堆叠闪电战的照片。您需要确保订阅者收到一个http请求,然后将结果分配给所需的变量。

enter image description here