【问题标题】:Angular http service loopAngular http服务循环
【发布时间】:2017-10-23 16:51:55
【问题描述】:

今天我面临着一个新的服务问题。

我正在尝试创建一个 http 服务,但是当我尝试在我的服务中存储 http.get.map 返回的 Observable 对象时 - 我的应用程序崩溃了。

我想实现一个“系统”,其中服务循环更新数据,订阅 observable 的组件根据服务的数据更新其数据。

代码如下:

afficheur.component.ts:

import { Component } from '@angular/core';
import {HardwareService} from "../../services/hardware.service";

@Component({
    selector: 'afficheur',
    templateUrl: 'app/components/hardware/afficheur.component.html'
})
export class AfficheurComponent{
    public state: Boolean;
    constructor(private service: HardwareService){
        this.service
            .getHardware()
            .subscribe(data => (console.log(data), this.state = data.afficheur),
                error => console.log(error),
                () => console.log('Get etat afficheur complete'))
    }
}

hardware.service.ts:

import { Injectable, OnInit }              from '@angular/core';
import { Headers, Http, Response }          from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

@Injectable()
export class HardwareService implements OnInit{
    private apiUrl = 'http://10.72.23.11:5000';  // URL to web API

    private ressources: Observable<any>;

    constructor (private http: Http) {}

    ngOnInit() {
        this.loopupdate()
    }

    loopupdate(): void {
        setInterval(() => {
            this.update();
        }, 5000);
    }

    update(): void {
        this.ressources = this.http.get(this.apiUrl)
            .map(this.extractData)
            .catch(this.handleError);
    }

    getHardware(){
        return this.ressources;
    }

    private extractData(res: Response) {
        let body = res.json();
        return body || { };
    }
    private handleError (error: Response | any) {
        // In a real world app, you might use a remote logging infrastructure
        let errMsg: string;
        if (error instanceof Response) {
            const body = error.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
    }
}

app.module.ts:

    import { FormsModule } from '@angular/forms';
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { HttpModule }    from '@angular/http';

    import { AppComponent } from './app.component';


    import { ROUTING } from './app.routes';
    import {HardwareService} from "./services/hardware.service";
    import {AfficheurComponent} from "./components/hardware/afficheur.component";
    import {HardwareListComponent} from "./views/hardwarelist/hardwarelist.component";


    @NgModule({
        imports: [ BrowserModule, ROUTING, HttpModule, FormsModule, HttpModule],
        declarations: [
            AppComponent,
            AfficheurComponent,
            HardwareListComponent
        ],
        bootstrap: [ AppComponent ],
        providers: [ HardwareService ]
    })

export class AppModule { }

再次感谢您来到这里:D

编辑:

当我尝试启动我的应用程序时出现错误:

ERROR TypeError: Cannot read property 'subscribe' of undefined

我认为这与 this.ressources 初始化有关,知道吗?


编辑 2: 在我的服务中:

initializePolling(){
        return IntervalObservable.create(5000)
            .flatMap(() => {
                return this.getHardware()
        });
    }

getHardware(): Observable<any> {
        return this.http.get(this.apiUrl)
            .map(this.extractData)
            .catch(this.handleError);
    }

如何使用我的组件订阅此内容?如果我有多个组件,我不知道我应该在组件中调用什么方法来获取数据而无需多次调用。

【问题讨论】:

    标签: javascript angular typescript angular-services angular-http


    【解决方案1】:

    问题在于ngOnInit(),就像您的Injectable 类中的那个一样,是一个Lifecycle hook,它只适用于指令组件强>。您应该尝试从 Injectable 类的 constructor 中调用 this.loopUpdate()。您可以通过another thread/question了解更多信息。

    如果要设置获取数据的时间间隔,请在组件类中进行,而不是在服务中。在服务中,您应该只有通过调用 http.get()... 返回 Observables(在您的情况下)的方法。这样一来,您就不会返回未定义的对象和更可重用的服务。

    另外,here's another SO link 给你看看。

    【讨论】:

    • 我将立即更新我的帖子,但出现错误。我使用 ngOnInit() 因为我想要启动 Observable,我认为这是这里的问题导致“错误类型错误:无法读取未定义的属性'订阅'”,知道吗?
    • @JérémyJOKE 更新了我的答案。
    • 问题是我的所有组件都使用相同的服务(提供者),所以如果我创建 2 个 afficheur.component,它会将 api 上的调用次数乘以 2。这就是为什么我希望服务循环并且组件根据服务的数据更新自己。
    • @JérémyJOKE 在我的答案中添加了另一个 SO 链接。
    • 我的组件如何订阅 Observable (IntervalObservable) ?我不知道怎么弄明白。帖子在 2 秒内更新
    猜你喜欢
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多