【问题标题】:Ionic 4 Subscribe only fires when page is loaded directlyIonic 4订阅仅在页面直接加载时触发
【发布时间】:2019-11-16 10:24:04
【问题描述】:

我在 Ionic 4 页面中的订阅有问题。当我直接在浏览器中通过其路由加载页面时,就会触发 subscribe 方法。如果我通过路由器链接导航到该页面,则不会触发订阅方法。

我正在使用Ionic Tabs 并阅读了一些 GitHub 问题,这些问题表明生命周期事件在选项卡导航之间无法正常工作。

请从我的页面 (score.page.ts) 中查看以下代码:

ngAfterViewInit() {
    console.log('ngAfterViewInit');
    this.productService.points.subscribe(
        (e) => console.log('score points', e)
    );
}

ionViewDidLoad() { console.log('ionViewDidLoad'); }

ngOnInit(): void {
    console.log('ngOnInit');
}

ionViewWillEnter() { console.log('ionViewWillEnter'); }

ionViewDidEnter() { console.log('ionViewDidEnter'); }

ionViewWillLeave() { console.log('ionViewWillLeave'); }

ionViewDidLeave() { console.log('ionViewDidLeave'); }

ionViewWillUnload() { console.log('ionViewWillUnload'); }

ngOnDestroy() {
    console.log('ngOnDestroy');
}

直接加载/app/home/score的控制台输出:

如您所见,生命周期事件正常工作,并且订阅方法已按预期调用。


当我加载 /app/home 并导航到 /app/home/score(我尝试了 routerlink 和 router.navigate)时,订阅的控制台日志丢失:

这是一个大问题,因为我需要在不同的页面上动态显示数据,如果我无法从我的服务订阅 Observable,这是不可能的。

我还在模板中尝试了{{ productService.points | async }},因为此后 Angular 处理订阅本身,但错误保持不变。

productService.pointsObservable<Number> 类型,但错误也发生在其他 Observables 上。

我应该为此提出问题还是我只是遗漏了什么?
如果您需要其他内容,请发表评论。

提前致谢

【问题讨论】:

  • 你能告诉我你在什么时候发出数据意味着 this.productService.points
  • this.points = this.transactions.pipe( map((transactions) => transactions.map(t => t.points)), map((t) => t.reduce((sum, points) => sum + points)) ); points 是从 firestore 的 vaueChanges() 函数转换而来的数组

标签: angular ionic-framework observable ionic4


【解决方案1】:

这不是订阅的问题,成功订阅只会在可观察的this.productService.points 发出任何东西时执行。您应该检查是什么导致 observable 在直接导航时发出而不是在使用选项卡时发出。

您可以通过将订阅分配给变量和控制台来确认订阅是否已附加。记录订阅对象。

const iSubscription: Subscription = this.productService.points.subscribe(
        (e) => console.log('score points', e)
    );
console.log(iSubscription);

【讨论】:

  • 感谢您的回答,但我在附加的订阅中没有看到您的意思。我已经尝试将订阅保存在变量中并记录下来,但我没有看到任何相关数据。 Observable 从我的服务发出,从 Firestore 获取它的数据。该服务被注入到我的 HomePage 和我的 ScorePage 中,因此应该正确发出。什么可以阻止 Observable 发出值?
  • 好吧,我明白你的意思了!因为我的ProductService 中的points 在我订阅它之前发出,所以订阅根本不会获得任何价值。相反,我需要使用 BehaviorSubject 例如,因为每次订阅它都会发出最后一个值。 This 帮助我理解了。
  • 我很高兴您的问题通过使用 BehaviorSubject 得以解决。
【解决方案2】:

解决方案是使用 BehaviorSubject(或 ReplaySubject)而不是 Observable

请查看此answer,以及此blog post

Subject 有一个特殊性阻止我们使用它来构建可观察的数据服务:如果我们订阅它,我们将无法获得最后一个值,我们将不得不等到应用程序的某些部分调用 next()。

这会带来一个问题,尤其是在引导情况下,应用仍在初始化并且并非所有订阅者都已注册,例如,并非所有异步管道都有机会注册自己,因为并非所有模板都已初始化。

一旦我能提供一个工作代码示例,我会尽快更新这个答案。

【讨论】:

    猜你喜欢
    • 2014-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多