【问题标题】:Ionic Components are not destroyed after navigation to another page导航到另一个页面后,离子组件不会被破坏
【发布时间】:2019-03-03 12:51:45
【问题描述】:

我目前正在处理项目是 Angular 6、Ionic 4 混合的遗留代码。所有功能模块都在延迟加载。

问题是导航到另一个页面后,我可以在导航工具的内存选项卡上看到前一页仍然存在,ngOnDestroy 并没有真正被触发。

为了给你更多细节,我的 app-routing-module 是:

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { routes } from './app.routes';


 @NgModule({
imports: [RouterModule.forRoot(routes, { enableTracing: false, useHash: false  
 })],
  exports: [RouterModule],
 })
 export class AppRoutingModule { }  

我的路线是:

  export const routes: Routes = [
     { 
       path: '', redirectTo: '/home',
       pathMatch: 'full' 
     },
     { 
     path: 'accounts',
     loadChildren: 
    '../pages/accounts/accounts.page.module#AccountsPageModule',
      canActivate: [AuthGuardService] 
     },
     {
     path: 'administration',
     loadChildren:      
'../pages/administration/administration.page.module#AdministrationPageModule' 
     },
    { 
     path: 'bookings',
     loadChildren: 
     '../pages/bookings/bookings.page.module#BookingsPageModule',
     canActivate: [AuthGuardService],

  },

在 app.component.html 中,加上一个ion-menu 结构的路由器:

 <ion-router-outlet id="content" swipeBackEnabled="false"></ion-router-outlet>

最后在每个链接的导航栏组件中,我使用路由器的[routerLink]="['/something']" 指令。

导航工作正常。问题是,一段时间后,网站速度非常慢,因为即使用户被导航到另一个页面并且 Angular 应该已经破坏了之前的页面,它仍然在内存中保留了每个组件、页面和模块。

我正在使用:

  • 角度:6.1.7
  • 离子:4.1.2

【问题讨论】:

  • 嗯不完全是。我尝试使用路由器事件并调用 ngOnDestroy 但页面组件和功能模块仍将在内存中
  • 是的,这很有趣。因为我在浏览器上,所以我不需要“清理”或删除加载的模块和组件。您是否对组件和模块都尝试过 OnDestroy?
  • 我也在浏览器上。你的意思是你把所有的东西都保存在内存中?这不会导致性能问题吗?我也对模块进行了尝试,但不幸的是那里也没有调用 ngOnDestroy。
  • 老实说,我没有内存问题。将 preloadingStrategy 更改为 NoPreloading 后,应用程序的初始加载时间显着减少。我在我的应用程序中使用了很多选项卡,每个选项卡都是一个组件。好吧,如果单击选项卡,我将 *ngIf 添加到组件中,这将是真实的。这将从 DOM 中删除模板,并允许垃圾收集在当前不在视图中的所有其他选项卡上执行其操作。

标签: angular ionic-framework


【解决方案1】:

我终于知道为什么了。

  • 我从应用程序中完全删除了 ionic 并仅使用 Angular 路由器进行导航。

现在每次我导航到另一个页面时都会调用 ngOnDestroy,并且页面本身会从 DOM 中删除。

【讨论】:

【解决方案2】:

导航和销毁和初始化挂钩上的离子缓存页面不起作用。

如果您需要对导航执行一些操作,则需要使用ionic-router-outlet 钩子。

  • ionViewWillEnter - 当被路由到的组件即将到达时触发 动画。
  • ionViewDidEnter - 当组件被路由到时触发 动画了。
  • ionViewWillLeave - 当被路由的组件是 即将制作动画。
  • ionViewDidLeave - 当被路由的组件有 动画。

您不需要使用OnInitOnDestroy 之类的任何接口。只需使用钩子即可。

例子:

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent {
  ionViewDidLeave() {
    // Do actions here
  }
}

【讨论】:

    【解决方案3】:

    如果您使用离子路由(&lt;ion-router-outlet&gt;{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }),如另一个答案中所述,页面被缓存并导航到其他页面,ngOnDestroy 不会被调用。

    如果你不想这样,请使用来自 NavContrller 的navigateRoot()

    this.navController.navigateRoot(['some-route']);

    并且用户将无法滑回上一页。

    【讨论】:

    • 如果 Ionic 可以在使用 ion-tabs 组件时提供使用 navigateRoot 的选项会很好
    • 为什么没有关于 navController 的文档?我找不到它,它对我有用。
    【解决方案4】:

    我正在使用 ionic 4 和 angular。对我有用的是在导航中添加 { replaceUrl: true }

    this.router.navigate([page.url], { replaceUrl: true });
    

    或在模板上

    <a [routerLink]="page.url" replaceUrl="true">...
    

    【讨论】:

    • 嗨,“this.router.navigate([page.url], { replaceUrl: true });”。这可以按预期进行导航。在导航到其他屏幕时,它开始导致点击不起作用的问题(页面可能隐藏在任何图层下)。不确定它的原因。
    【解决方案5】:

    replaceUrldefaultHref 设置为上一页以外的另一页会影响后退按钮导航

    【讨论】:

      【解决方案6】:

      对我来说,ionViewWillEnter 在我需要更改导航到的页面的视图时从页面导航出去时提供了帮助。

      【讨论】:

        【解决方案7】:

        在我的例子中,我有一个 &lt;video-player&gt; 自定义组件,当我导航到下一页时它不会被破坏。

        假设我有一个视频播放器路由,例如 /video/videoId1

        此页面名为VideoComponent,并有一个简化的模板,如下所示:

        <ion-content>
           <video-player [src]="videoUrl"></video-player>
           <ion-button>Next</ion-button>
        </ion-content>
        

        此页面的功能类似于通过视频播放列表的视频播放器。所以&lt;ion-button&gt; 只是导航到播放列表中的下一个视频,它本质上是导航到具有不同 URL 参数的相同组件,例如:

        /video/videoId2
        /video/videoId3
        

        当发生向前导航时,前一个播放器仍会继续播放视频。这只是不断添加,所以如果我们正在观看播放列表中的第四个视频,最后三个视频仍在后台播放。

        我在VideoPlayerComponent 上尝试过ngOnDestroyionViewWillLeaveionViewDidLeave,但没有任何调用。所以我只是硬编码代码来强制停止&lt;ion-button&gt;点击处理程序上的播放器。

        如果我将ngOnDestroyionViewWillLeaveionViewDidLeave 放在父VideoComponent 上,它会被正确调用,但从那里我无法访问VideoPlayerComponent 组件中的方法。我可能可以使用 Subject 或 Input 将数据传递到子组件,但对于基本的组件生命周期处理来说,这似乎有点过头了。

        【讨论】:

          猜你喜欢
          • 2020-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-11
          • 1970-01-01
          • 2020-06-29
          • 1970-01-01
          相关资源
          最近更新 更多