【问题标题】:Angular 2 - Observable and async http loadingAngular 2 - 可观察和异步 http 加载
【发布时间】:2016-05-03 15:53:49
【问题描述】:

这些天我一直在为 angular2 苦苦挣扎,目前我遇到了一些与异步 http 加载相关的问题。

这是我得到的:

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

我想做的事:

当我调用 "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;
        });
    } 
}

【问题讨论】:

    标签: http typescript angular observable


    【解决方案1】:

    这应该做你想做的:

    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

    【讨论】:

    • 嘿,君特!我认为您有错字/您在 sn-p 中遗漏了某些内容。 this.observable 永远不会设置...我认为类似:this.observable = this.httpService.getDocumentDataProviderTree...
    • 刚刚试了一下,它完全符合我的需要。谢谢!
    • 很高兴听到。感谢您的反馈:)
    猜你喜欢
    • 1970-01-01
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多