【问题标题】:How to access observable data from a class in the component?如何从组件中的类访问可观察数据?
【发布时间】:2019-08-22 18:06:51
【问题描述】:

我已经在一个单独的类中使用 observable 从 API 中声明了我想要的数据。我想将单独类中声明的数据访问到我的组件类中。但是一旦控件越过可观察方法的函数调用,javascript本质上是异步的会给我undefined。那么有没有办法“订阅”这个函数,该函数已经包含一个正在获取数据的可观察对象,或者以任何其他方式从 GetDataClass.ts 中的 getData() 访问数据到我的 Component 类中?

代码如下: GetDataClass.ts

  Data: any;
  getData() {
          this.dataservice.getAllData()
               .subscribe(response => {
                    this.temp = response;
                    this.Data = this.temp.ReturnData.DataList;
                    console.log('this.data new: ', this.Data);
               }, err => console.log('error: ', err))
     }

AppComponent:

data: any;
constructor(private dataService: GetDataClass ...){
    this.dataService.getData();
    this.data = this.dataService.temp
}

}

【问题讨论】:

    标签: angular rxjs observable


    【解决方案1】:

    我假设您希望“共享”可观察值,因为您不希望对同一组数据向服务器端发出多个请求。

    您可以使用多个 RxJS 运算符,例如 publishReplay()shareReplay()

    例如,在您的dataservice 中,我们可以修改getData 以利用publishReplay() 来触发缓存值。

    import { publishReplay, refCount } from 'rxjs/operators';
    
    getData() {
      return this.http.get(`api-request`)
        .pipe(
          publishReplay(1),
          refCount()
        );
    }
    

    同样,我们可以使用shareReplay

    import { shareReplay } from 'rxjs/operators';
    
    getData() {
      return this.http.get(`api-request`)
        .pipe(
          shareReplay({refCount: true, bufferSize: 1})
        );
    }
    

    在您的AppComponent 课程中,您可以照常订阅getData(),但要避免对同一端点的多个请求。

    res: any;
    
    ngOnInit(){
      this.dataService.getData().subscribe(data => {
        this.res = data;
      });
    }
    

    【讨论】:

      【解决方案2】:

      假设您有获取数据的class A 和使用数据的class B,您可以执行以下操作:

      • A中创建一个主题,这样每次有新数据进来,就可以发出数据。您还需要将此主题公开为公共可观察对象,以便其他消费者可以在数据进入时收到通知:
      // `A` class
      private _data$ = new Subject();
      data$ = this._data$.asObservable();
      
      getData () {
       this.apiService.get(...)
         .subscribe(results => {
          this._data$.next(results);
       })
      }
      
      • 创建class A 的消费者。在这种情况下,它将被称为class B。在这里,您将导入 A 类并订阅它公开的 observable:
      // `B` class
      
      constructor (private aService: AService) { }
      
      ngOnInit () {
       this.aService.getData();
      
       // Subscribe so you can get the new data every time
       this.aService.data$
        .subscribe(data => {
         // Do something with the data..
       })
      }
      

      【讨论】:

      • 从 observable 返回数据的方法非常糟糕
      • AFAIK,这实际上是一种常见的做事方式。您能否详细说明为什么这是一种不好的做法?
      • 如果你已经有一个 Observable,似乎没必要再创建一个 Subject 来包装它?
      • 是的,share() 操作符实际上会为您包装主题,无需重新发明轮子。
      • @DeborahK 现在我明白了。我最初认为在 A 类中也需要传入的数据。否则,这似乎确实没有必要,我可以简单地从“getData”返回 observable。感谢您的反馈!
      猜你喜欢
      • 2015-08-11
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 2016-10-28
      • 2016-12-26
      • 1970-01-01
      • 2016-05-14
      • 2018-12-16
      相关资源
      最近更新 更多