在 Ionic 5 路由器中登录/注销时登录/主页不会被破坏

Posted

技术标签:

【中文标题】在 Ionic 5 路由器中登录/注销时登录/主页不会被破坏【英文标题】:Login/Home pages not destroyed when login/logout in Ionic 5 router 【发布时间】:2020-09-30 08:45:47 【问题描述】:

我的项目在 IONIC 5 和 Firstore 中。有 2 种不同的 ion-router-outlet 用于经过身份验证的 (Home) 和未经身份验证的 (Index) 路由。以下是为app.component.ts类中的用户动态打开登录/主页的代码。

  this.afAuth.authState.subscribe(user => 
    if (user) 
      this.router.navigateByUrl('home');
     else 
      this.router.navigateByUrl('index');
    
  ); 

流程:登录页面->(登录)->主页->(注销)->登录页面。当主页打开时,登录页面仍然加载并在导航堆栈中。登录页面的ngOnDestroy 不执行。注销后,登录页面再次打开,但类constructorngOnInit 方法不执行。这会导致很多问题,因为页面初始化没有重新加载。流程主页->(注销)->登录页面->(登录)->主页发生了同样的问题。 如何销毁登录后的登录页面和注销后的主页,以便在同一会话中重新打开时可以重新加载?

编辑:

以下是路由配置:

app-routing.module.ts

const routes: Routes = [
  
    path: 'home',
    canLoad: [AuthGuard],
    loadChildren: () => import('./home/home.module').then(m => m.HomePageModule)
  ,
  
    path: 'index',
    loadChildren: () => import('./index/index.module').then(m => m.IndexPageModule)
  ,
];

Home.htmlIndex.html 具有相同的以下代码。

<ion-content>
  <ion-router-outlet></ion-router-outlet>
</ion-content>

index-routing.module.ts

const routes: Routes = [
  
    path: '',
    component: IndexPage,
    children:[
      
        path: '',
        loadChildren: () => import('../pages/login/login.module').then( m => m.LoginPageModule)
      ,
    ]
  
];

home-routing.module.ts

const routes: Routes = [
  
    path: '',
    component: HomePage,
    children:[
      
        path: '',
        loadChildren: () => import('../pages/user/user.module').then( m => m.UserPageModule)
      ,
.....
Other authenticated pages
]

【问题讨论】:

你能显示你的路线配置吗? 我在原帖中添加了。谢谢。 代替ngOnDestroyngOnInit,你不能使用离子页面生命周期中可用的钩子吗:ionViewWillEnter()ionViewDidEnter()ionViewWillLeaveionViewDidLeave @TapasMukherjee 你的两个路由器插座放在哪里? @AakashGarg 在 scr>app 文件夹中,有两个文件夹分别用于 home 和 index。我使用 ionic g 页面创建了这些。路由器位于 HTML 页面中。 【参考方案1】:

可行的最简单的解决方案,您应该使用“replaceUrl”NavigationExtras 导航到路线

this.router.navigate(['/home'], replaceUrl: true );

这将替换历史记录中的当前状态,因此您的登录页面将被销毁。基本上它设置了一个新的根。

Reference

【讨论】:

我在使用方法 navigatebyurl 之前尝试使用 'replaceUrl: true' 选项,但有时从登录页面导航到主页无法正常工作,我没有找到合适的解决方案,但现在可以使用导航方法。谢谢。【参考方案2】:

您所描述的看似意外的行为是由于 Ionic。更具体地说,是由于how Ionic deals with the life of a page。

当您导航到新页面时,Ionic 会将旧页面保留在 现有的 DOM,但从您的视图中隐藏它并转换新页面。

...

由于这种特殊处理,ngOnInit 和 ngOnDestroy 方法可能不会在您通常认为应该触发的时候触发。

ngOnInit 只会在每次新创建页面时触发,但不会 当导航回页面时。例如,在每个之间导航 选项卡界面中的页面只会调用每个页面的 ngOnInit 方法 一次,但不会在随后的访问中。 ngOnDestroy 只会在 页面“弹出”。

在对您的应用程序了解不多的情况下,我建议您使用Ionic Lifecycle events 而不是 Angular 的页面组件。听起来您可以将ngOnInit 替换为ionViewWillEnter 并将ngOnDestroy 替换为ionViewWillLeaveionViewDidLeave

文档的更下方是一些有用的guidance for each lifecycle method

【讨论】:

感谢您的详细解释。它与使用 'replaceUrl: true' 选项一起工作。生命周期钩子可以完成这项工作,但我还必须编写额外的代码来进行清理和初始化。【参考方案3】:

我认为您正面临销毁前一页的问题。 在 Iconic 中,当您导航到另一个页面时,它仍然保留 DOM 中的前一个页面。

所以你的 ngOnDestroy() 没有被调用。

您只需将 navigate() 函数替换为 navigateRoot()。这将解决您的问题并完全被破坏。

所以你的代码行应该有点像:

 this.afAuth.authState.subscribe(user => 
  if (user) 
    this.router.navigateRoot('home');
   else 
    this.router.navigateRoot('index');
  
 ); 

希望这能解决您的问题。

【讨论】:

路由器没有navigationRoot函数。

以上是关于在 Ionic 5 路由器中登录/注销时登录/主页不会被破坏的主要内容,如果未能解决你的问题,请参考以下文章

退出 Flutter 应用程序不会返回登录页面

使用 Ionic 2,您如何通过登录后将您发送到另一个页面的模式来更改基于登录状态的按钮?

用户登录并重定向到主页后,如何在主页导航栏中隐藏登录链接并显示注销链接?

登录和注销后如何重定向 - laravel 5

13 Servlet——session案例2:用户登录主页显示用户名和注销登录

登录时如何处理状态(Ionic、Firebase、AngularJS)?