Skip to content

Commit 7777237

Browse files
committed
feat(app): getActiveNav() method
1 parent fe31ebf commit 7777237

File tree

6 files changed

+201
-11
lines changed

6 files changed

+201
-11
lines changed

ionic/components/app/app.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import {Injectable, NgZone} from 'angular2/core';
1+
import {Injectable} from 'angular2/core';
22
import {Title} from 'angular2/platform/browser';
33

44
import {Config} from '../../config/config';
55
import {ClickBlock} from '../../util/click-block';
6-
import {rafFrames} from '../../util/dom';
6+
import {Nav} from '../nav/nav';
7+
import {Tabs} from '../tabs/tabs';
78

89

910
/**
@@ -18,11 +19,11 @@ export class IonicApp {
1819
private _title: string = '';
1920
private _titleSrv: Title = new Title();
2021
private _isProd: boolean = false;
22+
private _rootNav: any = null;
2123

2224
constructor(
2325
private _config: Config,
24-
private _clickBlock: ClickBlock,
25-
private _zone: NgZone
26+
private _clickBlock: ClickBlock
2627
) {}
2728

2829
/**
@@ -98,6 +99,38 @@ export class IonicApp {
9899
return (this._scrollTime + 64 > Date.now());
99100
}
100101

102+
/**
103+
* @private
104+
*/
105+
getActiveNav(): Nav | Tabs {
106+
var nav = this._rootNav || null;
107+
var activeChildNav;
108+
109+
while (nav) {
110+
activeChildNav = nav.getActiveChildNav();
111+
if (!activeChildNav) {
112+
break;
113+
}
114+
nav = activeChildNav;
115+
}
116+
117+
return nav;
118+
}
119+
120+
/**
121+
* @private
122+
*/
123+
getRootNav(): any {
124+
return this._rootNav;
125+
}
126+
127+
/**
128+
* @private
129+
*/
130+
setRootNav(nav: any) {
131+
this._rootNav = nav;
132+
}
133+
101134
/**
102135
* @private
103136
* Register a known component with a key, for easy lookups later.

ionic/components/app/test/app.spec.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import {IonicApp, Nav, Tabs, Tab, NavOptions, Config, ViewController} from '../../../../ionic';
2+
3+
export function run() {
4+
5+
6+
describe('IonicApp', () => {
7+
8+
describe('getActiveNav', () => {
9+
10+
it('should get active NavController when using tabs with nested nav', () => {
11+
let nav = mockNav();
12+
app.setRootNav(nav);
13+
14+
let tabs = mockTabs();
15+
let tab1 = mockTab(tabs);
16+
let tab2 = mockTab(tabs);
17+
nav.registerChildNav(tabs);
18+
19+
tab2.setSelected(true);
20+
let nav2 = mockNav();
21+
let nav3 = mockNav();
22+
let nav4 = mockNav();
23+
tab1.registerChildNav(nav4);
24+
tab2.registerChildNav(nav2);
25+
tab2.registerChildNav(nav3);
26+
27+
expect(app.getActiveNav()).toBe(nav3);
28+
});
29+
30+
it('should get active NavController when using tabs', () => {
31+
let nav = mockNav();
32+
app.setRootNav(nav);
33+
34+
let tabs = mockTabs();
35+
let tab1 = mockTab(tabs);
36+
let tab2 = mockTab(tabs);
37+
let tab3 = mockTab(tabs);
38+
nav.registerChildNav(tabs);
39+
40+
tab2.setSelected(true);
41+
42+
expect(app.getActiveNav()).toBe(tab2);
43+
44+
tab2.setSelected(false);
45+
tab3.setSelected(true);
46+
expect(app.getActiveNav()).toBe(tab3);
47+
});
48+
49+
it('should get active NavController when nested 3 deep', () => {
50+
let nav1 = mockNav();
51+
let nav2 = mockNav();
52+
let nav3 = mockNav();
53+
app.setRootNav(nav1);
54+
55+
nav1.registerChildNav(nav2);
56+
nav2.registerChildNav(nav3);
57+
58+
expect(app.getActiveNav()).toBe(nav3);
59+
});
60+
61+
it('should get active NavController when nested 2 deep', () => {
62+
let nav1 = mockNav();
63+
let nav2 = mockNav();
64+
app.setRootNav(nav1);
65+
66+
nav1.registerChildNav(nav2);
67+
expect(app.getActiveNav()).toBe(nav2);
68+
});
69+
70+
it('should get active NavController when only one nav controller', () => {
71+
let nav = mockNav();
72+
app.setRootNav(nav);
73+
expect(app.getActiveNav()).toBe(nav);
74+
});
75+
76+
it('should set/get the root nav controller', () => {
77+
let nav = mockNav();
78+
app.setRootNav(nav);
79+
expect(app.getRootNav()).toBe(nav);
80+
});
81+
82+
it('should not get an active NavController if there is not root set', () => {
83+
expect(app.getActiveNav()).toBeNull();
84+
expect(app.getRootNav()).toBeNull();
85+
});
86+
87+
});
88+
89+
var app: IonicApp;
90+
var config: Config;
91+
92+
function mockNav(): Nav {
93+
return new Nav(null,null,null,config,null,null,null,null,null,null);
94+
}
95+
96+
function mockTabs(): Tabs {
97+
return new Tabs(null, null, null, config, null, null, null);
98+
}
99+
100+
function mockTab(parentTabs: Tabs): Tab {
101+
return new Tab(parentTabs,null,config,null,null,null,null,null,null);
102+
}
103+
104+
beforeEach(() => {
105+
config = new Config();
106+
app = new IonicApp(config, null);
107+
});
108+
109+
});
110+
111+
112+
}

ionic/components/nav/nav-controller.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ export class NavController extends Ion {
110110
private _sbGesture: SwipeBackGesture;
111111
private _sbThreshold: number;
112112
private _portal: Portal;
113+
private _children: any[] = [];
113114

114115
protected _sbEnabled: boolean;
115116
protected _ids: number = -1;
@@ -166,8 +167,8 @@ export class NavController extends Ion {
166167

167168
this._trnsDelay = config.get('pageTransitionDelay');
168169

169-
this._sbEnabled = config.getBoolean('swipeBackEnabled') || false;
170-
this._sbThreshold = config.get('swipeBackThreshold') || 40;
170+
this._sbEnabled = config.getBoolean('swipeBackEnabled');
171+
this._sbThreshold = config.getNumber('swipeBackThreshold', 40);
171172

172173
this.id = (++ctrlIds).toString();
173174

@@ -1322,14 +1323,33 @@ export class NavController extends Ion {
13221323
}
13231324
}
13241325

1326+
getActiveChildNav(): any {
1327+
return this._children[this._children.length - 1];
1328+
}
1329+
1330+
registerChildNav(nav: any) {
1331+
this._children.push(nav);
1332+
}
1333+
1334+
unregisterChildNav(nav: any) {
1335+
let index = this._children.indexOf(nav);
1336+
if (index > -1) {
1337+
this._children.splice(index, 1);
1338+
}
1339+
}
1340+
13251341
/**
13261342
* @private
13271343
*/
13281344
ngOnDestroy() {
13291345
for (var i = this._views.length - 1; i >= 0; i--) {
13301346
this._views[i].destroy();
13311347
}
1332-
this._views = [];
1348+
this._views.length = 0;
1349+
1350+
if (this.parent) {
1351+
this.parent.unregisterChildNav(this);
1352+
}
13331353
}
13341354

13351355
/**

ionic/components/nav/nav.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export class Nav extends NavController {
113113
private _hasInit: boolean = false;
114114

115115
constructor(
116-
@Optional() hostNavCtrl: NavController,
116+
@Optional() parent: NavController,
117117
@Optional() viewCtrl: ViewController,
118118
app: IonicApp,
119119
config: Config,
@@ -124,14 +124,23 @@ export class Nav extends NavController {
124124
zone: NgZone,
125125
renderer: Renderer
126126
) {
127-
super(hostNavCtrl, app, config, keyboard, elementRef, 'contents', compiler, viewManager, zone, renderer);
127+
super(parent, app, config, keyboard, elementRef, 'contents', compiler, viewManager, zone, renderer);
128128

129129
if (viewCtrl) {
130130
// an ion-nav can also act as an ion-page within a parent ion-nav
131131
// this would happen when an ion-nav nests a child ion-nav.
132132
viewCtrl.setContent(this);
133133
viewCtrl.setContentRef(elementRef);
134134
}
135+
136+
if (parent) {
137+
// this Nav has a parent Nav
138+
parent.registerChildNav(this);
139+
140+
} else if (app) {
141+
// this is the root navcontroller for the entire app
142+
this._app.setRootNav(this);
143+
}
135144
}
136145

137146
/**

ionic/components/tabs/tab.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class Tab extends NavController {
9292
private _panelId: string;
9393
private _btnId: string;
9494
private _loaded: boolean;
95-
private _loadTmr: number;
95+
private _loadTmr: any;
9696

9797
/**
9898
* @private

ionic/components/tabs/tabs.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ export class Tabs extends Ion {
135135
parent: any;
136136

137137
constructor(
138-
@Optional() viewCtrl: ViewController,
139138
@Optional() parent: NavController,
139+
@Optional() viewCtrl: ViewController,
140140
private _app: IonicApp,
141141
private _config: Config,
142142
private _elementRef: ElementRef,
@@ -149,6 +149,15 @@ export class Tabs extends Ion {
149149
this.subPages = _config.getBoolean('tabSubPages');
150150
this._useHighlight = _config.getBoolean('tabbarHighlight');
151151

152+
if (parent) {
153+
// this Tabs has a parent Nav
154+
parent.registerChildNav(this);
155+
156+
} else if (this._app) {
157+
// this is the root navcontroller for the entire app
158+
this._app.setRootNav(this);
159+
}
160+
152161
// Tabs may also be an actual ViewController which was navigated to
153162
// if Tabs is static and not navigated to within a NavController
154163
// then skip this and don't treat it as it's own ViewController
@@ -308,6 +317,13 @@ export class Tabs extends Ion {
308317
return null;
309318
}
310319

320+
/**
321+
* @private
322+
*/
323+
getActiveChildNav() {
324+
return this.getSelected();
325+
}
326+
311327
/**
312328
* @private
313329
*/

0 commit comments

Comments
 (0)