使用Angular 2/4中的Observable定期使用http服务中的数据

时间:2017-05-28 17:55:28

标签: angular reactive-programming typescript2.0 angular2-observables

我正在学习使用angular(4)作为我的REST api后端的前端。

我目前有一个PostList组件,显示帖子列表。我正在使用返回的Observable>在我的daoService中,并在我的PostListComponent中的onInit中包含它。 这一切都很好,我很满意它,但是我想使用像interval这样的东西自动拨打这个电话,比如5秒。 我最初尝试遵循https://angular.io/docs/ts/latest/tutorial/toh-pt6.html#!#sts=Observables官方角度网站中看到的一些类似模式,但是用例不同,我的项目结构不足以让我以有用的方式跟随它有真正的问题。最终放弃了。我有很多谷歌,我正在努力找到一种直接的方式,我可以使用观察者/订阅者模式定期消耗我的api中的数据。

关于我如何调整以下代码来定期进行调用的任何建议对我来说都非常有用,而且我想,很多其他开发人员都是新角色。

import { Injectable } from '@angular/core';
import { Http, RequestOptions } from '@angular/http';
import {Post} from '../class/post';
import 'rxjs/add/operator/toPromise';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class PostDaoService      {

  private jwt: String;

  private commentsUrl = 'http://MYDOMAIN/posts';

  constructor(private http: Http, private opt: RequestOptions) {
    // tslint:disable-next-line:max-line-length
    this.jwt = 'eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJQYXNjYNFHUHSFWQiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ.4D9TUDQAgIWAooyiMN1lV8Y5wVCrIF4rAeGzFzelSE9diqHMik9WE9x4EsNnEcxQXYATjxAZovpp-m72LpFADA';
   }

  getPosts(): Observable<Array<Post>> {
    this.opt.headers.set('Authorization', 'Bearer ' + this.jwt);
    this.opt.headers.set('Content-Type', 'application/json');
    return this.http.get(this.commentsUrl)
      .map((response) => response.json())
      .map((data: any) => {
        return data._embedded.posts as Post[];
      });
  }
}

import { ContextMenuService } from '../../../baseui-module/context-menu/context-menu.service';

import { Post } from '../../class/post';
import { PostDaoService } from '../../service/post-dao.service';
import {Component, Input, OnInit} from '@angular/core';

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

  posts: Post[];

  constructor(public service: ContextMenuService, public dao: PostDaoService) { }

  ngOnInit() {
    this.service.postItems();
    this.dao.getPosts().subscribe((data: Array<Post>) => {
      this.posts = data;
    });
  }

  public getItems(): Post[] {
    return this.posts;
  }
}

1 个答案:

答案 0 :(得分:0)

诀窍是使用mergeMap / flatMap(取决于你的rxjs版本):

getPosts(trigger: Observable<any>): Observable<Array<Post>> {
  this.opt.headers.set('Authorization', 'Bearer ' + this.jwt);
  this.opt.headers.set('Content-Type', 'application/json');
  return trigger.flatMap(() =>
     this.http.get(this.commentsUrl)
      .map((response) => response.json())
      .map((data: any) => {
        return data._embedded.posts as Post[];
      });
}

然后在你的组件中:

this.dao.getPosts(Observable.timerInterval(0, 5000)
   .subscribe(data => ....);

显然你可以将它与其他触发器一起使用:

this.dao.getPosts(Observable.fromEvent(refreshButton, 'click'))

单击刷新按钮时刷新

顺便说一下,你可能想避免订阅而是定义:

this.posts$ = this.dao.getPosts(...);

并在您的模板中:

<any *ngFor="let post of posts$">post display here</any>

这样可以提高效率,降低用户和内存泄漏的风险。