我希望能够使用.subscribe
访问我方法之外的数据
这是我的服务"工作"细
getSessionTracker(): Observable<ISessionTracker[]> {
return this.http.get(this._url)
.map((res: Response) => {
let data = res.json();
return data;
})
.catch(this.handleError)
}
组件是我遇到麻烦的地方
sessionTrackers: ISessionTracker[] = []; // object array
this.trackerService.getSessionTracker()
.subscribe((sessionTrackers: ISessionTracker[]) => {
this.sessionTrackers = sessionTrackers;
console.log('real data in subscribe', this.sessionTrackers[0].SessionId);
},
(err: any) => console.log(err),
() => console.log('getSessionTracker()'));
//在功能之外,这不起作用
console.log('real data', this.sessionTrackers);
2个问题
this.sessionTrackers[0].SessionId
未定义,但是this.this.sessionTrackers
如何保存数据?
答案 0 :(得分:5)
问题是时间问题。由于服务调用是异步的,因此在调用subscribe时数据不会立即到达。相反,当从服务返回响应时,将调用定义为subscribe方法的参数的回调函数。
这就是为什么Subscribe中的console.log工作的原因。
这是一张大致概述执行顺序的图片。
但是,您的代码将在确实检索时保留该值。
因此,在subscribe函数之外,您只需检查值是否存在。像这样:
if (this.sessionTrackers) { console.log(...) }
或者如果您绑定数据,则需要使用*ngIf
或安全导航操作符(?)。
如果您使用的是反应形式,那么您可能需要单独设置表单模型(使用FormBuilder)并设置默认值。
我在这里有一个反应形式的例子:https://github.com/DeborahK/Angular2-ReactiveForms(查看APM文件夹)。
<强> ngOnInit 强>
ngOnInit(): void {
this.productForm = this.fb.group({
productName: ['', [Validators.required,
Validators.minLength(3),
Validators.maxLength(50)]],
productCode: ['', Validators.required],
starRating: ['', NumberValidators.range(1, 5)],
tags: this.fb.array([]),
description: ''
});
// Read the product Id from the route parameter
this.sub = this.route.params.subscribe(
params => {
let id = +params['id'];
this.getProduct(id);
}
);
}
此代码设置反应形式并监视路径参数的更改。设置route参数后,调用getProduct(id)。
<强> getProduct 强>
getProduct(id: number): void {
this.productService.getProduct(id)
.subscribe(
(product: IProduct) => this.onProductRetrieved(product),
(error: any) => this.errorMessage = <any>error
);
}
这可以获得数据,有点类似于你正在做的事情。请注意,在订阅回调中,我调用了另一种方法:onProductRetrieved
。
<强> onProductRetrieved 强>
onProductRetrieved(product: IProduct): void {
if (this.productForm) {
this.productForm.reset();
}
this.product = product;
// Update the data on the form
this.productForm.patchValue({
productName: this.product.productName,
productCode: this.product.productCode,
starRating: this.product.starRating,
description: this.product.description
});
this.productForm.setControl('tags', this.fb.array(this.product.tags || []));
}
这是我设置反应形式的默认值的地方,因为我现在知道我拥有数据。您可以使用setValue
或patchValue
。