【问题标题】:Nativescript : Lifecycle missing onPause/onResume ? Should I stop subscriptions when page is navigatedFrom/away?Nativescript:生命周期缺少 onPause/onResume 吗?当页面从/离开时,我应该停止订阅吗?
【发布时间】:2020-02-06 09:19:49
【问题描述】:

我认为我在 NativeScript 中遗漏了一些东西(目前使用 Angular 并在 Android 上进行测试,都是最新版本)。

一方面,我的每条路线都会初始化一些 Observable Subscription(观察数据变化、导航变化、服务变化)。 另一方面,Nativescript 保留了一堆已加载/正在运行的路由..

结果:如果我的任何服务发生变化,堆叠路由上的订阅仍会执行(不在屏幕上,但可以在后栈深处)..

这是个问题吗?我的意思是为什么那些隐藏的路线仍然有效?是不是闻起来像漏水一样难闻?

所以现在,我在问,为什么 Nativescript 没有 Android Sdk 上的 onResume 和 onPause 逻辑?这样我可以从这里停止/恢复观察者?

目前,我正在尝试使用:

ngOnInit() {
    console.log('onInit');
}

@HostListener('loaded')
onResume() {
    console.log('onResume');
}

@HostListener('unloaded')
onPause() {
    console.log('onPause');
}

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

但我不知道,我对这一切有一种不好的感觉,我觉得我不是应该处理这个问题的人,而是 nativescript inner sdk。谢谢。

【问题讨论】:

  • nativescript支持挂起和恢复,如application.on(application.resumeEvent),docs.nativescript.org/core-concepts/application-lifecycle
  • @Yong 我说的不是应用程序生命周期,而是页面(组件或路由)生命周期
  • 您可以在组件中注册回调。
  • NativeScript 中的页面是一种布局 - 它不是 Android Activity。所以因为这不是一个活动,而是一个没有onResume 的视图(但有loaded 事件)

标签: angular typescript rxjs nativescript angular2-nativescript


【解决方案1】:

您可以在 NS Angular 文档中查看此页面:

https://docs.nativescript.org/angular/core-concepts/angular-navigation

尤其是这个部分:

In a native mobile application, the system will keep the navigated views alive,
so that when you come back to them, their view state will be kept the same.
Views are destroyed only when you back away from them. The page-router-outlet
houses native navigations, so its components lifecycle must match the lifecycle
of the native views. This is done by the custom NSRouteReuseStrategy.

为了取消订阅,我使用了一个 BaseComponent 来跟踪组件的所有订阅,并在 ngOnDestroy 中删除它们 - 最终将被调用。

在极少数情况下,我需要在 NativeScript 生命周期挂钩中执行此操作,即。如果需要特殊处理,请在 page.on('navigatedFrom') 中。

【讨论】:

  • 感谢您的回答。是的,我已经做了所有这些,但我的问题仍然存在:当您的页面不是活动页面并且在后台堆栈中时,您的所有订阅仍然执行对您来说可以吗?那感觉很糟糕。从性能的角度来看,这对我来说是一个漏洞......所以我将使用加载/卸载事件,但它有点 hacky
  • 性能影响将取决于您在订阅中所做的事情以及您的后台堆栈可以达到多深,但我没有遇到任何问题(我知道) - 除了有点恼火必须牢记与“web”Angular 的差异。
【解决方案2】:

加载或卸载是在 {N} 个视图上触发的事件。它是基础组件,由框架中的任何其他组件继承。 loaded 事件在底层原生视图创建时触发,unloaded 主要是在其被销毁或从屏幕上移除时触发。

您的Page(分配给路由路径的任何组件都用 Angular 中的 Page 包装)是一个片段。当您使用page-router-outlet 向前导航时,您的当前页面将被放在一个后退堆栈(历史记录)中。此时也可以调用unloaded 事件,但这并不一定意味着您必须取消订阅。由于组件在返回堆栈上仍然存在,当您向后导航时,loaded 将再次被触发。

我建议你坚持使用ngOnInit 订阅和ngOnDestroy 取消订阅任何东西,就像网络上的 Angular 一样。只有在必须访问 UI 元素/它是底层原生组件的情况下,才应使用 View 的 loaded 事件。但请记住,每次加载页面时都会触发此事件,包括上面讨论的后退导航。因此,您可能希望在完成后立即删除加载的侦听器,这样它就不会在返回导航时再次执行。

此外,如果您在将组件放在后台堆栈时保持订阅处于活动状态,也不会影响性能。我相信原生视图不会更新,除非它处于活动状态。但是如果您在控制器上执行任何繁重的操作,例如一些繁重的数学或长循环等,您可能想要取消订阅,这完全取决于您在订阅中所做的事情。

【讨论】:

    猜你喜欢
    • 2013-10-04
    • 2015-05-13
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多