我在使用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),
() => {}
)
}
}
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
}
}
答案 0 :(得分:5)
回答我自己的问题:
在app root中,使用以下命令导入Rxjs:
import 'rxjs/Rx';
这使您可以访问完整的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
}
)
}
}
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
}
}
感谢Gunter和Mark的回复,帮助我绕过这一点,我觉得我更了解Observables,经历了很多解决这个问题的文档!
答案 1 :(得分:2)
检查结果是否已经到达,如果是,则创建一个新的保证并用结果完成,但不是,获取它,并将其作为保证返回。
@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);
}
}
}
我不知道TS,这段代码可能包含一些错误(我只使用Angular Dart),但你应该明白这一点。
另见
- http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html
答案 2 :(得分:0)
那么你可以使用回调函数,
举个例子 考虑这是post函数,它触发服务模块中的post服务
postData(id: string, name: string) {
console.log("Got you",id);
this._employeeService.postServices({id: id, name: name})
.subscribe(
(response:Response) => this.consoleMyOutput(),
error => console.log(error)
);
}
这里注意函数consoleMyOutput()
。
一旦在调用服务后获得响应,就会触发此操作
现在,
consoleMyOutput(){console.log("Write Your call back function")};
此功能将在此之后触发。
答案 3 :(得分:0)
只需使用Rxjs方法就可以实现,这里是在应用程序加载后调用服务的简单而经典的方法,然后我们可以将它订阅到多个组件中。 确保服务应该可以重用于所有组件,因此可以在服务和映射中执行代码,只在组件中进行订阅:
服务:
import { Injectable } from 'angular2/core';
import { Http } from 'angular2/http';
@Injectable()
export class Service {
result: Object;
constructor(private http: Http) {}
private _urlGet = '/api';
httpGet(){
return this.http.get(this._urlGet)
.map(res => JSON.parse(res.json()))
.do(result => {
this.result = result;
}, error => console.log(error))
}
}
<强>组件强>
export class Component {
formattedResult: Object;
constructor(private service: Service) { }
ngOnInit(){
this.service.httpGet().subscribe(result => {
this.formattedResult = result;
}
}
}