【问题标题】:Periodically consume data from http service using Observable in Angular 2 / 4使用 Angular 2 / 4 中的 Observable 定期使用来自 http 服务的数据
【发布时间】:2017-05-28 17:55:28
【问题描述】:

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

我目前有一个显示帖子列表的 PostList 组件。我在我的 daoService 中使用一个返回的 Observable>,并在我的 PostListComponent 内的 onInit 中订阅它。 这一切都很好,我对它很满意,但是我想使用间隔之类的东西来自动进行这个调用,比如 5 秒。 我最初尝试遵循一些类似的模式,如在https://angular.io/docs/ts/latest/tutorial/toh-pt6.html#!#sts=Observables 的官方角度站点中看到的,但是用例足够不同,我的项目结构也足够不同,以至于我以一种有用的方式遵循它并最终给出了真正的问题向上。我有很多谷歌,并且正在努力寻找一种简单的方法来定期使用观察者/订阅者模式从我的 api 消费数据。

任何关于我如何调整以下代码以每隔一段时间进行调用的建议对我来说都是非常有用的,而且我想,很多其他开发人员都是 Angular 的新手。

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

【问题讨论】:

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


    【解决方案1】:

    诀窍是使用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>
    

    这将更有效,并降低悬空订阅者和内存泄漏的风险。

    【讨论】:

    • 不幸的是 timerInterval(n, m) 在 Observable 中不可用,所以我改为 interval(5000) 修复了编译错误,但是我现在收到以下错误:core.es5.js:1084 ERROR 错误:未捕获(承诺中):TypeError:WEBPACK_IMPORTED_MODULE_3_rxjs_Observable.Observable.interval 不是函数 TypeError:WEBPACK_IMPORTED_MODULE_3_rxjs_Observable.Observable.interval 不是函数
    • 您添加了导入吗?我认为是 import 'rxjs/observable/add/interval'
    • 我刚刚明确导入了它,现在它说 flatMap(或 mergeMap)不是一个函数。尝试明确导入这些但无处可去。编辑:另外,如果我暂时将 Observable 对象的触发器变量与 .这样我就可以检查 api,这些功能都不可用
    • 取决于 rxjs 的版本。在 SO 上查看一下,看看需要做什么,例如:github.com/angular/angular/issues/8167
    • 事实证明,我的很多问题是我的 IDE 没有以正确的方式导入一些东西。此外,我的 IDE 可以毫无问题地为 Observable 的函数(例如)提供智能代码建议而没有错误,但实际上使它们在运行时可用于 Angular 需要单独的显式导入。感谢你的帮助。现在排序。
    猜你喜欢
    • 2023-04-09
    • 2017-10-12
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    • 2018-02-14
    • 2017-02-02
    • 1970-01-01
    • 2018-02-21
    相关资源
    最近更新 更多