【问题标题】:Sharing same Observable from a Service in Pages/Components从页面/组件中的服务共享相同的 Observable
【发布时间】:2018-06-18 17:05:36
【问题描述】:

我正在尝试多次订阅相同的Observable,但它不起作用。我有一个提供者,它给了我来自AngularFirestore 对象的Observable。这是我的提供者:

@Injectable()
export class MyProvider {
  private myObservable: Observable<any>;
  constructor(private aFs: AngularFirestore) {
    //retriving some data and putting in myObservable
  }

  getObservable() {
    return this.myObservable;
  }
}

在我的myPage.ts 我这样做:

this.mySubscription = this.myProvider.getObservable().subscribe(value => {
  //something that works
});

在另一个组件中我也这样做,但它没有给我任何东西。如何从服务或提供商共享Observable?我试过unsubscribe()它,当我从我的页面弹出到组件时,当我在组件上调用unsubscribe()然后我导航到我的页面时,subscribe()不起作用。

在我的页面中发送unsubscribe()

ionViewWillLeave() {
  this.mySubscription.unsubscribe();
}

到我的组件中的unsubscribe(),在我导航到我的页面之前,我会这样做:

myEvent() {
  this.mySubscription.unsubscribe();
  this.navCtrl.push(MyPage);
}

当我从 MyPage 弹出时,unsubscribe() 似乎工作正常,因为我可以在我的组件中看到 myObservable 数据。当我尝试从我的组件导航到MyPage 时,unsubscribe() 似乎不起作用,因为我什么也看不到。我也尝试过调试,但在第二种情况下,subscribe() 什么也看不到。

我在providers 下的app.module.ts 中导入我的提供程序,然后在我的页面中导入它:

MyPage.ts

import { MyProvider } from ..;

构造函数(MyPage.ts):

constructor(private myProvider: MyProvider) {..}

在我的组件中:

我的组件.ts

import { MyProvider } from ..;

构造函数(Home.ts)

constructor(private myProvider: MyProvider) {..}

我澄清MyComponent 没有在MyPage 中使用!我在Home 中使用它,然后我用它推送到MyPage。我这样做是因为我想在MyComponent 中显示简单数据,然后我想推送到包含数据详细信息的MyPage

很容易,我想在组件和页面上共享从服务​​中检索到的同一个 Observable,并且我想在两者上都 subscribe() 它。这可能吗?

【问题讨论】:

  • 您确定提供者是作为单例提供的吗?
  • 不,我也这么认为,但我不明白如何使它成为单例。我正在使用打字稿,这是我第一次尝试提供者。
  • 你能说明你在哪里提供/导入 Provider 吗?
  • 我更新了问题。
  • 分享你的 app.module.ts.

标签: angular ionic-framework rxjs observable


【解决方案1】:

如果您的目标是多播数据,请使用 RXJS 的 SubjectBehaviorSubject
Subject 充当源 Observable 和许多 observers 之间的桥梁/代理,从而可以使用多个 @ 987654328@ 共享相同的Observable 执行。
这种公开主题的推荐方式是使用asObservable() 运算符。

@Injectable()
export class MyProvider {
  private myObservable=new Subject<any>();
  CurrentData = this.myObservable.asObservable();
  constructor(private aFs: AngularFirestore) {
    //your logic
      this.myObservable.next(value);//push data into observable
  }


}

Page.ts

this.mySubscription = this.myProvider.CurrentData.subscribe(value => {
      //something that works
    });

使用行为主题

 @Injectable()
    export class MyProvider {
      private myObservable=new BehaviorSubject<any>('');
      CurrentData = this.myObservable.asObservable();
      constructor(private aFs: AngularFirestore) {

      }

     getData(myParam): void { 
       someasynccall.pipe(map(),filter()).
          subscribe(value=>this.myObservable.next(value))


    }

Page.ts

this.myProvider.getData(param);
this.mySubscription = this.myProvider.CurrentData.subscribe(value => {
      //something that works
    });

Subject vs BehaviorSubject

LiveDemo

【讨论】:

  • 如果我想用参数打电话怎么办?我想要 currentData 取决于我传递给提供者的参数。喜欢getData(myParam): Observable&lt;any&gt; { //dothings like filter or map; myObservable.subscribe(value =&gt; { this.currentData.next(value) }); return this.currentData.asObservable(); }
  • 您在拨打Http 电话吗?
  • 我不完全理解您的要求,但您无法从 subscribe 回调中返回值您正在使用异步编程您需要等到您的订阅解决后再采取适当的措施
  • 我已经更新了我的代码,并提供了一个工作的 stackblitz 看看
  • 你的代码是对的,我在想这样的事情,但我的行为是不同的。 behaviorSubject 每次都“传递”给我一个不同的 Observable,并且使用 next 方法我添加 observables,所以每次我添加一些东西时,我都必须在之前添加 .next([]) 因为我可以在新调用中可视化旧值。跨度>
猜你喜欢
  • 2018-06-03
  • 1970-01-01
  • 2022-11-09
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多