Angular 2 - Observable和async http加载

时间:2016-05-02 23:17:42

标签: http typescript angular observable

这些天我一直在与angular2挣扎,而且我目前仍然遇到与async http loading相关的一些问题。

这是我得到的:

  • 1个服务组件(MyCustomHttpService),包含对REST API执行http调用的方法
  • 1类(DataProvider),必须使用检索到的数据填充属性
  • 一个调用类的getter以便将数据推送到视图的视图组件(MyCmp)

我想做什么:

当我打电话给“DataProvider.getDataProviderSpecification()”

  • 我加载数据(如果尚未加载)
  • 否则,我会返回已加载的数据

此逻辑必须位于DataProvider类中,而不是位于自定义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;
        });
    } 
}

1 个答案:

答案 0 :(得分:3)

这应该做你想要的:

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;
    }
}    

另见https://stackoverflow.com/a/36291681/217408