使用 Angular 观察者通过网络获取数据
Using Angular Observers to fetch data over a network
我正在开发一个 Angular 应用程序,其中包含用户可以添加的(金融)交易列表。这一切进展顺利,我正在尝试从服务提供的静态列表切换到尝试从本地 Node.js 服务器获取数据。我正在使用观察者异步获取交易列表。
我一直在关注 Angular 的 HTTP tutorial and the associated plunker。但是,即使我可以看到来自服务器的数据,我也无法使用 .subscribe() 方法从中获取一组有用的数据。
这是我连接到节点服务器的服务:
@Injectable()
export class TradeService {
private url = '...'; // URL to web API
tradeArray: Trade[] = [];
constructor(private http: Http) { }
//-----------GETTERS---------------//
getTradeObservable(): Observable<Trade> {
return this.http.get(this.url)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
console.log("body:" + body);
console.log("Entire Body.trades: " + body.trades);
return body.trades;
}
getTrades(): any {
this.getTradeObservable()
.subscribe(
trade => this.tradeArray.push(trade));
return this.tradeArray;
}
这里是节点服务器本身的相关部分:
var TRADES = { "trades": [
{"id": 0, "cust": "Ben", "hasSub": true,
"subcust": "Rigby", "type": "s", "security": "001", "ticket": "99"},
...
{"id": 9, "cust": "Uber Bank", "hasSub": true,
"subcust": "Lil Bank", "type": "p", "security": "456", "ticket": "56"}
]};
////////////Get Requests/////////////////
//this route returns all data in JSON format
app.get('/', function(req, res) {
res.send(JSON.stringify(TRADES));
});
以及 getTrades 的预期输出:
[
{id: 0, cust: "Ben", hasSub: true,
subCust: "Rigby", type: "s", security: '001', ticket: '99'},
...
{id: 9, cust: "Uber Bank", hasSub: true,
subCust: "Lil' Bank", type: "p", security: '456', ticket: '56'},
];
服务被注入和调用的地方之一:
export class SubmittedComponent {
constructor(private tradeService: TradeService) { }
//initally show all trades
rows = this.tradeService.getTrades();
...
我可以在浏览器控制台中看到 'entire body.trades' 是我想要的数据的完整列表,但订阅似乎没有将它们推送到 tradeArray,最终未定义。
感谢您的宝贵时间。
所以我假设您正在从您的组件之一调用 getTrades()。如果是这种情况,将发生以下情况:
- 请求将被发送
- 请求将在后台异步处理
- 该方法不会等待请求得到解决,而是 return tradeArray 的当前值,即 []
为避免这种情况,您可以重构组件,以便它们调用 getTradeObservable()
方法并订阅 returned Observable
.
更新:另一种选择是重构您的服务以使用 Subject', and expose it to your components through an
Observable`。
更新:假设您有以下贸易定义
export interface Trade{
id: number;
cust: string;
hasSub: boolean;
subCust: string;
type: string;s
security: string;
ticket: string;
}
您可以尝试以下方法
class TestComponent {
data: Trade[];
// inject service in component
getData(){
this.service.getTradesObservable().subscribe(data => this.data = data);
}
}
并将 getTradesObservable 的定义更改为:
getTradeObservable(): Observable<Trade[]> {
return this.http.get(this.url)
.map(this.extractData)
.catch(this.handleError);
}
只说这部分代码:
getTrades(): any {
this.getTradeObservable()
.subscribe(
trade => this.tradeArray.push(trade));
return this.tradeArray;
}
因为 getTradeObservable
是异步的,这一行:return this.tradeArray;
将(可能)在可观察对象被解析之前执行,你应该从你的服务中删除 getTrades
方法,而不是获取在您的组件中由 getTradeObservable
编辑的可观察对象 return 而不是期望整个事情 return 您想要的值,您应该在订阅中分配该值,如下所示:
@Component({
providers:[TradeService ]
})
export class myComponent{
trades:Trade[];
constructor(tradeService:TradeService){
tradeService.getTradeObservable().subscribe(tradeRes=>this.trades=tradeRes as Trade[]);
}
}
我正在开发一个 Angular 应用程序,其中包含用户可以添加的(金融)交易列表。这一切进展顺利,我正在尝试从服务提供的静态列表切换到尝试从本地 Node.js 服务器获取数据。我正在使用观察者异步获取交易列表。
我一直在关注 Angular 的 HTTP tutorial and the associated plunker。但是,即使我可以看到来自服务器的数据,我也无法使用 .subscribe() 方法从中获取一组有用的数据。
这是我连接到节点服务器的服务:
@Injectable()
export class TradeService {
private url = '...'; // URL to web API
tradeArray: Trade[] = [];
constructor(private http: Http) { }
//-----------GETTERS---------------//
getTradeObservable(): Observable<Trade> {
return this.http.get(this.url)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
console.log("body:" + body);
console.log("Entire Body.trades: " + body.trades);
return body.trades;
}
getTrades(): any {
this.getTradeObservable()
.subscribe(
trade => this.tradeArray.push(trade));
return this.tradeArray;
}
这里是节点服务器本身的相关部分:
var TRADES = { "trades": [
{"id": 0, "cust": "Ben", "hasSub": true,
"subcust": "Rigby", "type": "s", "security": "001", "ticket": "99"},
...
{"id": 9, "cust": "Uber Bank", "hasSub": true,
"subcust": "Lil Bank", "type": "p", "security": "456", "ticket": "56"}
]};
////////////Get Requests/////////////////
//this route returns all data in JSON format
app.get('/', function(req, res) {
res.send(JSON.stringify(TRADES));
});
以及 getTrades 的预期输出:
[
{id: 0, cust: "Ben", hasSub: true,
subCust: "Rigby", type: "s", security: '001', ticket: '99'},
...
{id: 9, cust: "Uber Bank", hasSub: true,
subCust: "Lil' Bank", type: "p", security: '456', ticket: '56'},
];
服务被注入和调用的地方之一:
export class SubmittedComponent {
constructor(private tradeService: TradeService) { }
//initally show all trades
rows = this.tradeService.getTrades();
...
我可以在浏览器控制台中看到 'entire body.trades' 是我想要的数据的完整列表,但订阅似乎没有将它们推送到 tradeArray,最终未定义。
感谢您的宝贵时间。
所以我假设您正在从您的组件之一调用 getTrades()。如果是这种情况,将发生以下情况:
- 请求将被发送
- 请求将在后台异步处理
- 该方法不会等待请求得到解决,而是 return tradeArray 的当前值,即 []
为避免这种情况,您可以重构组件,以便它们调用 getTradeObservable()
方法并订阅 returned Observable
.
更新:另一种选择是重构您的服务以使用 Subject', and expose it to your components through an
Observable`。
更新:假设您有以下贸易定义
export interface Trade{
id: number;
cust: string;
hasSub: boolean;
subCust: string;
type: string;s
security: string;
ticket: string;
}
您可以尝试以下方法
class TestComponent {
data: Trade[];
// inject service in component
getData(){
this.service.getTradesObservable().subscribe(data => this.data = data);
}
}
并将 getTradesObservable 的定义更改为:
getTradeObservable(): Observable<Trade[]> {
return this.http.get(this.url)
.map(this.extractData)
.catch(this.handleError);
}
只说这部分代码:
getTrades(): any {
this.getTradeObservable()
.subscribe(
trade => this.tradeArray.push(trade));
return this.tradeArray;
}
因为 getTradeObservable
是异步的,这一行:return this.tradeArray;
将(可能)在可观察对象被解析之前执行,你应该从你的服务中删除 getTrades
方法,而不是获取在您的组件中由 getTradeObservable
编辑的可观察对象 return 而不是期望整个事情 return 您想要的值,您应该在订阅中分配该值,如下所示:
@Component({
providers:[TradeService ]
})
export class myComponent{
trades:Trade[];
constructor(tradeService:TradeService){
tradeService.getTradeObservable().subscribe(tradeRes=>this.trades=tradeRes as Trade[]);
}
}