我对angular和rxjs很陌生.

在rxjs4.x中,我知道您可以使用Observable.interval(5000)来完成这项工作,但在rxjs5中似乎不存在. 我的解决办法目前使用<meta http-equiv="refresh" content="5" >刷新整个应用程序,这会重新加载整个页面,从而重新加载数据.

所以我真正想做的是,用一些方法来处理可观测数据,也许是判断是否发生了任何变化.或者只是重新加载数据.

任何帮助或其他/更好的方式都将不胜感激.

到目前为止我拥有的:

@Injectable()
export class DataService {

    constructor(private http:Http){}

    getData(url) {
        return this.http.get(url)
            .map(res => {
                return res.text();
            })
            .map(res => {
                return res.split("\n");
            })
            .map(res => {
                var dataModels: DataModel[] = [];
                res.forEach(str => {
                    var s = str.split(",");
                    if(s[0] !== "") {
                        dataModels.push(new DataModel(s[0], parseInt(s[1]), parseInt(s[2])));
                    }
                });
                return dataModels;
            })
    }
}

@Component({
selector: 'my-app',
template: `Some html to display the data`,
providers: [DataService],
export class AppComponent {

data:DataModel[];

constructor(dataService:DataService) {}

ngOnInit() {
    this.dataService.getData('url').subscribe(
        res => {
            this.data= res;

        },
        err => console.log(err),
        () => console.log("Data received")
        );
    }
}

依赖项:Package.json

"dependencies": {
  "angular2": "^2.0.0-beta.3",
  "bootstrap": "^4.0.0-alpha.2",
  "es6-promise": "^3.0.2",
  "es6-shim": "^0.33.13",
  "jquery": "^2.2.0",
  "reflect-metadata": "^0.1.2",
  "rxjs": "^5.0.0-beta.0",
  "systemjs": "^0.19.20",
  "zone.js": "^0.5.11"
},
"devDependencies": {
  "typescript": "^1.7.5"
}

指数html导入:

<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>

<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>

推荐答案

正如@Adam和@Ploppy提到的,可观察的.interval()现在已被弃用,并不是创建这样一个可观察对象的首选方法.这样做的首选方式是通过IntervalObservable或TimerObservable.

我想在这个答案中添加一些用法,以展示我在Angular 2框架中找到的最佳方法.

首先是您的服务(通过‘ng g service MyExample’命令在Angular cli中创建).假设该服务是REST风格的(http get请求返回一个json):

my-example.service.ts

import { Injectable } from '@angular/core';
import { Http, Response} from "@angular/http";
import { MyDataModel } from "./my-data-model";
import { Observable } from "rxjs";
import 'rxjs/Rx';

@Injectable()
export class MyExampleService {
  private url = 'http://localhost:3000'; // full uri of the service to consume here

  constructor(private http: Http) { }

  get(): Observable<MyDataModel>{
    return this.http
      .get(this.url)
      .map((res: Response) => res.json());
  }
}

***有关Angular 5,请参阅服务的底部更新***

现在,您的组件代码('ng g component MyExample'):

my-example.Component.ts:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { MyDataModel } from "../my-data-model";
import { MyExampleService } from "../my-example.service";
import { Observable } from "rxjs";
import { IntervalObservable } from "rxjs/observable/IntervalObservable";
import 'rxjs/add/operator/takeWhile';

@Component({
  selector: 'app-my-example',
  templateUrl: './my-example.component.html',
  styleUrls: ['./my-example.component.css']
})
export class MyExampleComponent implements OnInit, OnDestroy {
  private data: MyDataModel;
  private display: boolean; // whether to display info in the component
                            // use *ngIf="display" in your html to take
                            // advantage of this

  private alive: boolean; // used to unsubscribe from the IntervalObservable
                          // when OnDestroy is called.

  constructor(private myExampleService: MyExampleService) {
    this.display = false;
    this.alive = true;
  }

  ngOnInit() {
    // get our data immediately when the component inits
    this.myExampleService.get()
      .first() // only gets fired once
      .subscribe((data) => {
        this.data = data;
        this.display = true;
      });

    // get our data every subsequent 10 seconds
    IntervalObservable.create(10000)
      .takeWhile(() => this.alive) // only fires when component is alive
      .subscribe(() => {
        this.myExampleService.get()
          .subscribe(data => {
            this.data = data;
          });
      });
  }

  ngOnDestroy(){
    this.alive = false; // switches your IntervalObservable off
  }
}

==编辑===

更新了组件ts代码,以通过TimerObservable整合订阅:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { MyDataModel } from "../my-data-model";
import { MyExampleService } from "../my-example.service";
import { Observable } from "rxjs";
import { TimerObservable } from "rxjs/observable/TimerObservable";
import 'rxjs/add/operator/takeWhile';

@Component({
  selector: 'app-my-example',
  templateUrl: './my-example.component.html',
  styleUrls: ['./my-example.component.css']
})
export class MyExampleComponent implements OnInit, OnDestroy {
  private data: MyDataModel;
  private display: boolean; // whether to display info in the component
                            // use *ngIf="display" in your html to take
                            // advantage of this

  private alive: boolean; // used to unsubscribe from the TimerObservable
                          // when OnDestroy is called.
  private interval: number;

  constructor(private myExampleService: MyExampleService) {
    this.display = false;
    this.alive = true;
    this.interval = 10000;
  }

  ngOnInit() {
    TimerObservable.create(0, this.interval)
      .takeWhile(() => this.alive)
      .subscribe(() => {
        this.myExampleService.get()
          .subscribe((data) => {
            this.data = data;
            if(!this.display){
              this.display = true;
            }
          });
      });
  }

  ngOnDestroy(){
    this.alive = false; // switches your TimerObservable off
  }
}

==编辑===

my-example-service.ts(从5个Angular 使用HttpClient):

import { Injectable } from '@angular/core';
import { HttpClient} from "@angular/common/http";
import { MyDataModel } from "./my-data-model";
import { Observable } from "rxjs";
import 'rxjs/Rx';

@Injectable()
export class MyExampleService {
  private url = 'http://localhost:3000'; // full uri of the service to consume here

  constructor(private http: HttpClient) { }

  get(): Observable<MyDataModel>{
    return this.http
      .get<MyDataModel>(this.url);
  }
}

注意使用HttpClient而不是Http(angular5中不推荐使用)和get方法的更改,该方法允许在不使用rxjs的情况下将响应解析到我们的数据模型中.map()运算符.虽然angular 5的服务有所改变,但组件代码保持不变.

Angular相关问答推荐

Angular 16路卫单元测试可观察到的SpyObj属性

单元测试 case 模拟store 中的行为主体

添加@ nx/webpack插件 destruct 了Nativescript构建

间歇性不正确的SSR重定向(server. ts级别的请求和响应不匹配)

为什么这个拦截器只在发送事件上触发,而不是在实际响应上触发?

在Angular中将路由解析器提供程序和组件提供程序相结合

将sass与@Use语句一起使用时出现Angular 新的VITE构建器编译错误

元素上的Angular 管道链接不起作用

对Angular 为17的路径使用AuthGuard

错误TS2531:对象可能为空.论窗体数组控件

Moment.js 和 Angular 库

导入 AngularFirestoreModule 时出现问题:此类型参数可能需要 `extends firebase.firestore.DocumentData` 约束.

您如何链接需要多个先前可观察对象的依赖订阅

Angular:将间隔与增量和减量相结合

角项目更新

关闭 Dynamsoft Web Twain 弹出窗口

异步管道模板中的局部变量(Angular 2+)

带有重定向的Angular 2 AuthGuard服务?

如何在 Angular 2 中正确设置 Http 请求标头

Angular2:如果 img src 无效,则显示占位符图像