feature(angular): nav-params integrate with router

This commit is contained in:
Dan Bucholtz
2018-02-13 15:05:12 -06:00
parent f4d1c6f561
commit 8c8b8548e7
5 changed files with 57 additions and 16 deletions

View File

@ -125,7 +125,9 @@ export class RouterOutlet implements OnDestroy, OnInit, RouterDelegate {
const isTopLevel = !hasChildComponent(activatedRoute); const isTopLevel = !hasChildComponent(activatedRoute);
return this.routeEventHandler.externalNavStart().then(() => { return this.routeEventHandler.externalNavStart().then(() => {
return activateRoute(this.elementRef.nativeElement, component, cfr, injector, isTopLevel).then(() => { return getDataFromRoute(activatedRoute);
}).then((dataObj: any) => {
return activateRoute(this.elementRef.nativeElement, component, dataObj, cfr, injector, isTopLevel).then(() => {
this.changeDetector.markForCheck(); this.changeDetector.markForCheck();
this.activateEvents.emit(null); this.activateEvents.emit(null);
this.activationStatus = ACTIVATED; this.activationStatus = ACTIVATED;
@ -135,11 +137,11 @@ export class RouterOutlet implements OnDestroy, OnInit, RouterDelegate {
} }
export function activateRoute(navElement: HTMLIonNavElement, export function activateRoute(navElement: HTMLIonNavElement,
component: Type<any>, cfr: ComponentFactoryResolver, injector: Injector, isTopLevel: boolean): Promise<void> { component: Type<any>, data: any = {}, cfr: ComponentFactoryResolver, injector: Injector, isTopLevel: boolean): Promise<void> {
return ensureExternalRounterController().then((externalRouterController) => { return ensureExternalRounterController().then((externalRouterController) => {
const escapeHatch = getEscapeHatch(cfr, injector); const escapeHatch = getEscapeHatch(cfr, injector);
return externalRouterController.reconcileNav(navElement, component, escapeHatch, isTopLevel); return externalRouterController.reconcileNav(navElement, component, data, escapeHatch, isTopLevel);
}); });
} }
@ -165,3 +167,32 @@ export function getEscapeHatch(cfr: ComponentFactoryResolver, injector: Injector
url: location.pathname url: location.pathname
}; };
} }
export function getDataFromRoute(activatedRoute: ActivatedRoute): Promise<any> {
const promises: Promise<any>[] = [];
promises.push(getDataFromObservable(activatedRoute));
promises.push(getDataFromParams(activatedRoute));
return Promise.all(promises).then(([data, params]: any[]) => {
let combined = {};
Object.assign(combined, data, params);
return combined;
});
}
export function getDataFromObservable(activatedRoute: ActivatedRoute) {
return new Promise((resolve) => {
activatedRoute.data.subscribe((data: any) => {
resolve(data || {});
});
});
}
export function getDataFromParams(activatedRoute: ActivatedRoute) {
return new Promise((resolve) => {
activatedRoute.params.subscribe((data: any) => {
console.log('data: ', data);
resolve(data || {});
});
});
}

View File

@ -30,14 +30,14 @@ export class ExternalRouterController {
} }
@Method() @Method()
reconcileNav(nav: HTMLIonNavElement, component: any, escapeHatch: EscapeHatch, isTopLevel: boolean) { reconcileNav(nav: HTMLIonNavElement, component: any, data: any = {}, escapeHatch: EscapeHatch, isTopLevel: boolean) {
return nav.componentOnReady().then(() => { return nav.componentOnReady().then(() => {
// check if the nav has an `<ion-tab>` as a parent // check if the nav has an `<ion-tab>` as a parent
if (isParentTab(nav)) { if (isParentTab(nav)) {
// check if the tab is selected // check if the tab is selected
return updateTab(this, nav, component, escapeHatch, isTopLevel); return updateTab(this, nav, component, data, escapeHatch, isTopLevel);
} else { } else {
return updateNav(nav, component, escapeHatch, isTopLevel); return updateNav(nav, component, data, escapeHatch, isTopLevel);
} }
}); });
} }
@ -47,7 +47,7 @@ function isParentTab(navElement: HTMLIonNavElement) {
return navElement.parentElement.tagName.toLowerCase() === 'ion-tab'; return navElement.parentElement.tagName.toLowerCase() === 'ion-tab';
} }
function updateTab(externalRouterController: ExternalRouterController, navElement: HTMLIonNavElement, component: any, escapeHatch: EscapeHatch, isTopLevel: boolean) { function updateTab(externalRouterController: ExternalRouterController, navElement: HTMLIonNavElement, component: any, data: any, escapeHatch: EscapeHatch, isTopLevel: boolean) {
const tab = navElement.parentElement as HTMLIonTabElement; const tab = navElement.parentElement as HTMLIonTabElement;
@ -56,7 +56,7 @@ function updateTab(externalRouterController: ExternalRouterController, navElemen
return isTabSelected(tabs, tab).then((isSelected: boolean) => { return isTabSelected(tabs, tab).then((isSelected: boolean) => {
if (!isSelected) { if (!isSelected) {
const promise = updateNav(navElement, component, escapeHatch, isTopLevel); const promise = updateNav(navElement, component, data, escapeHatch, isTopLevel);
externalRouterController.externalNavPromise = promise; externalRouterController.externalNavPromise = promise;
// okay, the tab is not selected, so we need to do a "switch" transition // okay, the tab is not selected, so we need to do a "switch" transition
// basically, we should update the nav, and then swap the tabs // basically, we should update the nav, and then swap the tabs
@ -66,7 +66,7 @@ function updateTab(externalRouterController: ExternalRouterController, navElemen
} }
// okay cool, the tab is already selected, so we want to see a transition // okay cool, the tab is already selected, so we want to see a transition
return updateNav(navElement, component, escapeHatch, isTopLevel); return updateNav(navElement, component, data, escapeHatch, isTopLevel);
}); });
} }
@ -80,14 +80,14 @@ function isTabSelected(tabsElement: HTMLIonTabsElement, tabElement: HTMLIonTabEl
} }
function updateNav(navElement: HTMLIonNavElement, function updateNav(navElement: HTMLIonNavElement,
component: any, escapeHatch: EscapeHatch, isTopLevel: boolean): Promise<NavResult> { component: any, data: any, escapeHatch: EscapeHatch, isTopLevel: boolean): Promise<NavResult> {
// check if the component is the top view // check if the component is the top view
const activeViews = navElement.getViews(); const activeViews = navElement.getViews();
if (activeViews.length === 0) { if (activeViews.length === 0) {
// there isn't a view in the stack, so push one // there isn't a view in the stack, so push one
return navElement.setRoot(component, {}, {}, escapeHatch); return navElement.setRoot(component, data, {}, escapeHatch);
} }
const currentView = activeViews[activeViews.length - 1]; const currentView = activeViews[activeViews.length - 1];
@ -115,5 +115,5 @@ function updateNav(navElement: HTMLIonNavElement,
} }
// it's the top level nav, and it's not one of those other behaviors, so do a push so the user gets a chill animation // it's the top level nav, and it's not one of those other behaviors, so do a push so the user gets a chill animation
return navElement.push(component, {}, { animate: isTopLevel }, escapeHatch); return navElement.push(component, data, { animate: isTopLevel }, escapeHatch);
} }

View File

@ -1,5 +1,5 @@
import { Component, ViewEncapsulation } from '@angular/core'; import { Component, ViewEncapsulation } from '@angular/core';
import { NavController } from '@ionic/angular'; import { NavController, NavParams } from '@ionic/angular';
@Component({ @Component({
selector: 'page-three', selector: 'page-three',
@ -12,6 +12,9 @@ import { NavController } from '@ionic/angular';
</ion-header> </ion-header>
<ion-content padding> <ion-content padding>
Page Three {{ts}} Page Three {{ts}}
<div>isProd: {{isProd}}</div>
<div>paramOne: {{paramOne}}</div>
<div>paramTwo: {{paramTwo}}</div>
<div> <div>
<ion-button (click)="navPop()">Go Back</ion-button> <ion-button (click)="navPop()">Go Back</ion-button>
</div> </div>
@ -22,7 +25,14 @@ import { NavController } from '@ionic/angular';
export class PageThree { export class PageThree {
ts: number; ts: number;
constructor(private navController: NavController) { isProd = false;
paramOne: any = null;
paramTwo: any = null;
constructor(private navController: NavController, private navParams: NavParams) {
this.isProd = navParams.get('isProd');
this.paramOne = navParams.get('paramOne');
this.paramTwo = navParams.get('paramTwo');
setInterval(() => { setInterval(() => {
this.ts = Date.now(); this.ts = Date.now();

View File

@ -30,7 +30,7 @@ export class PageTwo {
} }
pushPageThreeComponent() { pushPageThreeComponent() {
this.navController.push('/simple-nav/page-three'); this.navController.push('/simple-nav/page-three/jim/halpert');
} }
goBack() { goBack() {

View File

@ -10,7 +10,7 @@ const routes: Routes = [
children: [ children: [
{ path: 'page-one', loadChildren: './page-one/page-one.module#PageOneModule' }, { path: 'page-one', loadChildren: './page-one/page-one.module#PageOneModule' },
{ path: 'page-two', loadChildren: './page-two/page-two.module#PageTwoModule' }, { path: 'page-two', loadChildren: './page-two/page-two.module#PageTwoModule' },
{ path: 'page-three', loadChildren: './page-three/page-three.module#PageThreeModule' } { path: 'page-three/:paramOne/:paramTwo', loadChildren: './page-three/page-three.module#PageThreeModule', data: { isProd: true} }
] ]
}, },
]; ];