Ionic 4开始选项卡项目生命周期挂钩断开



步骤1:

ionic start stacktabs tabs --type=angular
ionic cordova platform add android
ionic cordova run android --prod

一切正常。

步骤2:检查当前路线:

//START:app-routing.module.ts:

path: '',
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)

//结束:app-routing.module.ts:

//开始:选项卡-路由模块.ts:

const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{
path: 'tab1',
children: [
{
path: '',
loadChildren: () =>
import('../tab1/tab1.module').then(m => m.Tab1PageModule)
}
]
},
{
path: 'tab2',
children: [
{
path: '',
loadChildren: () =>
import('../tab2/tab2.module').then(m => m.Tab2PageModule)
}
]
},
{
path: 'tab3',
children: [
{
path: '',
loadChildren: () =>
import('../tab3/tab3.module').then(m => m.Tab3PageModule)
}
]
},
{
path: '',
redirectTo: '/tabs/tab1',
pathMatch: 'full'
}
]
},
{
path: '',
redirectTo: '/tabs/tab1',
pathMatch: 'full'
}
];  

//结束:选项卡-路由模块.ts:

步骤:3在中为构造函数、ionViewWillEnter、ionViewDidEnter添加console.log

tabs.page.ts
tab1.page.ts
tab2.page.ts
Re-run and everythings works as expected with the following console.log info:
Inside tabs.page.ts constructor()....
Inside tab1.page.ts constructor()....
Inside tab1.page.ts ionViewWillEnter()....
Inside tab1.page.ts ionViewDidEnter()....
Inside tabs.page.ts ionViewWillEnter()....
Inside tabs.page.ts ionViewDidEnter()....
Press tab2:
Inside tab2.page.ts constructor()....
Inside tab2.page.ts ionViewWillEnter()....
Inside tab2.page.ts ionViewDidEnter()....
Press tab1:
Inside tab1.page.ts ionViewWillEnter()....
Inside tab1.page.ts ionViewDidEnter()....

添加新页面:initPage

ionic g page initPage

检查app-routing.module.ts

const routes: Routes = [
{
path: '',
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
},
{
path: 'init-page',
loadChildren: () => import('./init-page/init-page.module').then( m => m.InitPagePageModule)
}
];

第4步:在tab1.page.html中添加离子按钮,该按钮将路由到initPage:

<ion-button expand="full" (click)="gotoInitPage()">Go to InitPage</ion-button>
gotoInitPage()
{
this.navController.navigateForward('/init-page');
}

initPage显示没有任何问题。

步骤5:在init-page.page.html中添加离子按钮,该按钮将返回选项卡页面:

<ion-button expand="full" (click)="backToTabsPage()">Back to TabsPage</ion-button>
backToTabsPage()
{
this.navController.navigateForward('/tabs/tab1');
}

注意:底部选项卡按钮和选项卡1页面显示在视图中,但来自chrome调试器:

tab1模块根本没有启动(只有tabs.page.ts被执行(:

仅显示选项卡页面日志

Inside tabs.page.ts ionViewWillEnter()....
Inside tabs.page.ts ionViewDidEnter()....

通过在initPage中添加后退按钮再次进行测试:结果是一样的,tab1页面模块没有启动。

<ion-header>
<ion-toolbar color="primary">
<ion-buttons slot="start">
<ion-back-button defaultHref="/tabs/tab1"></ion-back-button>
</ion-buttons>
<ion-title>InitPage</ion-title>
</ion-toolbar>
</ion-header>

我在initPage内部尝试了不同的路由方法,但没有成功:

this.navController.navigateRoot('/tabs/tab1');
this.router.navigateByUrl('/tabs/tab1');

环境:

Ionic CLI                     : 5.4.16 
Ionic Framework               : @ionic/angular 5.0.4
@angular-devkit/build-angular : 0.803.25
@angular-devkit/schematics    : 8.3.25
@angular/cli                  : 8.3.25
@ionic/angular-toolkit        : 2.2.0
Cordova:
Cordova CLI       : 9.0.0 (cordova-lib@9.0.1)
Cordova Platforms : android 8.1.0
Cordova Plugins   : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 4.1.3, (and 4 other plugins)
Utility:
cordova-res : 0.8.1
native-run  : 0.3.0
System:
Android SDK Tools : 26.1.1 (C:UserslouieAppDataLocalAndroidSdk)
NodeJS            : v12.14.0 (D:Program Filesnodejsnode.exe)
npm               : 6.13.4
OS                : Windows 10

请帮忙。。。提前感谢

只针对有同样问题的人。事实证明,你需要使用tab1页面内的this.navController.anavigateRoot('/some route'(。和在initPage中,您需要发出相同的命令,即this.navController.anavigateRoot('/tables/tab1'(;信用到此URL:https://www.joshmorony.com/using-angular-routing-with-ionic-4/

您可以对父路由使用canDeactivate guard。

完整的演示

const routes: Routes = [
{
path: '',
component: TabsComponent,
canDeactivate: [IonRouterOutletHooks],
}
}

import { Injectable, Injector } from '@angular/core';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
UrlTree,
CanDeactivate,
ActivatedRoute
} from '@angular/router';
import { Observable } from 'rxjs';
import { IonRouterOutlet } from '@ionic/angular';
import { LIFECYCLE_WILL_LEAVE, LIFECYCLE_DID_LEAVE } from '@ionic/core';
export interface INestedPageDeactivate {
ionRouterOutlet: IonRouterOutlet;
// activatedRoute: ActivatedRoute;
}
@Injectable()
export class IonRouterOutletHooks implements CanActivate, CanDeactivate<any> {
constructor(public injector: Injector) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree {
// console.log(this);
// console.log(route);
// console.log(state);
return true;
}
canDeactivate(
component: INestedPageDeactivate,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
// console.log(component);
// console.log(currentRoute);
// console.log(currentState);
// console.log(nextState);
if (!component.ionRouterOutlet) {
alert('IonRouterOutletHooks->component->ionRouterOutlet');
return false;
}
const stackCtrl = (component.ionRouterOutlet as any).stackCtrl;
stackCtrl.views.reverse().forEach((view) => {
if (!view.ref.hostView.destroyed){
view.element.dispatchEvent(new CustomEvent(LIFECYCLE_WILL_LEAVE, {
bubbles: false,
cancelable: false,
}));
view.element.dispatchEvent(new CustomEvent(LIFECYCLE_DID_LEAVE, {
bubbles: false,
cancelable: false,
}));
}
});
return true;
}
}

最新更新