Angular 2 - 可观察和异步 http 加载
Angular 2 - Observable and async http loading
这些天我一直在与 angular2 作斗争,目前我遇到了一些与异步 http 加载相关的问题。
这是我得到的:
- 1 个服务组件 (MyCustomHttpService) 包含对 REST 执行 http 调用的方法 API
- 1 class (DataProvider) 必须用检索到的数据填充属性
- 1 个视图组件 (MyCmp) 调用 class 的 getter 以便将数据推送到视图
我想做的事情:
当我打电话时 "DataProvider.getDataProviderSpecification()"
- 如果数据还没有加载我加载数据
- 否则,我return数据已经加载
此逻辑必须在 DataProvider class 中,而不是在自定义 http 服务或视图组件中。
我找到了一个真正肮脏的解决方法。因为我知道它真的很糟糕,所以我正在寻求有关如何改进那段代码的建议。
在此先感谢您的帮助。
看起来像这样(代码已清理):
/** CLASS **/
@Component()
export class DataProvider {
private treestructure: any = null;
constructor(private httpService: MyCustomHttpService) {}
public getDataProviderSpecification() {
if(this.treestructure == null) {
return Observable.create(observer => {
// http service to get REST data
this.httpService.getDocumentDataProviderTree(this.documentID)
.subscribe((tree)=> {
this.treestructure= tree;
observer.next(this.treestructure);
observer.complete();
});
});
} else {
return Observable.create(observer => {
observer.next(this.treestructure);
observer.complete();
});
}
}
...
}
/** VIEW COMPONENT **/
@Component({
selector: 'my-cmp',
template: '<tree-cmp [structure]="tree"></tree-cmp>',
inputs: ['dataprovider'],
directives: [TreeComponent]
})
export class MyCmp {
@Input() dataprovider: DataProvider;
tree: any;
showDetails(id) {
this.dataprovider.getDataProviderSpecification().subscribe((treestructure) => {
this.tree = treestructure;
});
}
}
这应该可以满足您的要求:
public getDataProviderSpecification() {
if(this.treestructure) {
return Observable.of(this.treestructure);
else if(this.observable) {
// if `this.observable` is set then the request is in progress
// return the `Observable` for the ongoing request
return this.observable;
} else {
// create the request, store the `Observable` for subsequent subscribers
this.observable = this.httpService.getDocumentDataProviderTree(this.documentID)
//.map(res => res.json())
.do(val => {
this.treestructure = val;
// when the cached data is available we don't need the `Observable` reference anymore
this.observable = null;
})
// make it shared so more than one subscriber can get the result
.share();
return this.observable;
}
}
另见
这些天我一直在与 angular2 作斗争,目前我遇到了一些与异步 http 加载相关的问题。
这是我得到的:
- 1 个服务组件 (MyCustomHttpService) 包含对 REST 执行 http 调用的方法 API
- 1 class (DataProvider) 必须用检索到的数据填充属性
- 1 个视图组件 (MyCmp) 调用 class 的 getter 以便将数据推送到视图
我想做的事情:
当我打电话时 "DataProvider.getDataProviderSpecification()"
- 如果数据还没有加载我加载数据
- 否则,我return数据已经加载
此逻辑必须在 DataProvider class 中,而不是在自定义 http 服务或视图组件中。
我找到了一个真正肮脏的解决方法。因为我知道它真的很糟糕,所以我正在寻求有关如何改进那段代码的建议。
在此先感谢您的帮助。
看起来像这样(代码已清理):
/** CLASS **/
@Component()
export class DataProvider {
private treestructure: any = null;
constructor(private httpService: MyCustomHttpService) {}
public getDataProviderSpecification() {
if(this.treestructure == null) {
return Observable.create(observer => {
// http service to get REST data
this.httpService.getDocumentDataProviderTree(this.documentID)
.subscribe((tree)=> {
this.treestructure= tree;
observer.next(this.treestructure);
observer.complete();
});
});
} else {
return Observable.create(observer => {
observer.next(this.treestructure);
observer.complete();
});
}
}
...
}
/** VIEW COMPONENT **/
@Component({
selector: 'my-cmp',
template: '<tree-cmp [structure]="tree"></tree-cmp>',
inputs: ['dataprovider'],
directives: [TreeComponent]
})
export class MyCmp {
@Input() dataprovider: DataProvider;
tree: any;
showDetails(id) {
this.dataprovider.getDataProviderSpecification().subscribe((treestructure) => {
this.tree = treestructure;
});
}
}
这应该可以满足您的要求:
public getDataProviderSpecification() {
if(this.treestructure) {
return Observable.of(this.treestructure);
else if(this.observable) {
// if `this.observable` is set then the request is in progress
// return the `Observable` for the ongoing request
return this.observable;
} else {
// create the request, store the `Observable` for subsequent subscribers
this.observable = this.httpService.getDocumentDataProviderTree(this.documentID)
//.map(res => res.json())
.do(val => {
this.treestructure = val;
// when the cached data is available we don't need the `Observable` reference anymore
this.observable = null;
})
// make it shared so more than one subscriber can get the result
.share();
return this.observable;
}
}
另见