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)
回答我自己的问题:
在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,经历了很多解决这个问题的文档!
检查结果是否已经到达,如果是,则创建一个新的 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