服务http.get调用完成后有组件执行功能

Pet*_*man 11 asynchronous observable rxjs angular

我真的很难绕着angular2中的观察者和订阅.我目前遇到的问题如下:

我有一个服务,其中包含从API发布和获取数据的方法.该服务被注入一个组件,该组件直接调用服务中的那些方法.然后,该服务检索数据并将其自身存储,但我想在组件中处理该数据.在服务检索并存储数据本身之后,我无法弄清楚如何使组件执行函数.

service.ts

import { Injectable } from 'angular2/core';    
import { Http } from 'angular2/router';

@Injectable()
export class Service {
    result: Object;

    constructor(http: Http) {
        this.http = http;
    }

    httpGet(url) {
        return this.http.get(url).subscribe(
            result => this.result = result.json(),
            error => console.log(error),
            () => {}
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

component.ts

import { Component } from 'angular2/core';
import { Service } from './service';

@Component({
    ...
})
export class Component {
    formattedResult: Object;

    constructor(service: Service) {
        this.service = service;
        this.service.httpGet('/api')

        // How do I call format result on service.result only after it is completed?
        this.formatResult(service.result) // Need to execute this after the http call is completed

        // I want something like:
        this.service.httpGet('/api').then(() => formatResult(this.service.result));
    }

    formatResult(result) {
        this.formattedResult = result.map(x => x.length) // For example
    }
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*man 5

回答我自己的问题:

在app root中,导入Rxjs:

import 'rxjs/Rx';
Run Code Online (Sandbox Code Playgroud)

这使您可以访问完整的Observable对象(不仅仅是Angular附带的'Observable-lite').这使您能够.map .reduce等Http请求.

现在,您可以在Http请求上使用.map在服务上下文中执行任意代码,即使它是订阅结果的组件.因此,为了实现我在开始时要做的事情,我们可以:

service.ts

import { Injectable } from 'angular2/core';    
import { Http } from 'angular2/router';

@Injectable()
export class Service {
    result: Object;

    constructor(http: Http) {
        this.http = http;
    }

    httpGet(url) {
        return this.http.get(url).map(
            result => {
                let data = result.json();
                this.result = data;
                return data
            }
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

component.ts

import { Component } from 'angular2/core';
import { Service } from './service';

@Component({
    // Component setup
})
export class Component {
    formattedResult: Object;

    constructor(service: Service) {
        this.service = service;
        this.service.httpGet('/api').subscribe(
            data => this.formatResult(data);
        );
    }

    formatResult(result) {
        this.formattedResult = result.map(x => x.length) // For example
    }
}
Run Code Online (Sandbox Code Playgroud)

感谢Gunter和Mark的回复,帮助我绕过这一点,我觉得我更了解Observables,经历了很多解决这个问题的文档!


Gün*_*uer 2

检查结果是否已经到达,如果是,则创建一个新的 Promise 并用结果完成它,否则,获取它,并将其作为 Promise 返回。

@Injectable()
export class Service {
    result: Object;

    constructor(http: Http) {
        this.http = http;
    }

    httpGet(url) {
        if(result === undefined) {
          return this.http.get(url).toPromise().then(
              result => this.result = result.json(),
              error => console.log(error);
          );
        } else {
          return new Promise().resolve(result);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道 TS 并且这段代码可能包含一些错误(我只使用 Angular Dart),但你应该明白了。

另请参阅
- http://blog.thoughtram.io/angular/2016/01/06/take-advantage-of-observables-in-angular2.html