Skip to content

Commit

Permalink
feat(app): getActiveNav() method
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdbradley committed Apr 8, 2016
1 parent fe31ebf commit 7777237
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 11 deletions.
41 changes: 37 additions & 4 deletions ionic/components/app/app.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {Injectable, NgZone} from 'angular2/core';
import {Injectable} from 'angular2/core';
import {Title} from 'angular2/platform/browser';

import {Config} from '../../config/config';
import {ClickBlock} from '../../util/click-block';
import {rafFrames} from '../../util/dom';
import {Nav} from '../nav/nav';
import {Tabs} from '../tabs/tabs';


/**
Expand All @@ -18,11 +19,11 @@ export class IonicApp {
private _title: string = '';
private _titleSrv: Title = new Title();
private _isProd: boolean = false;
private _rootNav: any = null;

constructor(
private _config: Config,
private _clickBlock: ClickBlock,
private _zone: NgZone
private _clickBlock: ClickBlock
) {}

/**
Expand Down Expand Up @@ -98,6 +99,38 @@ export class IonicApp {
return (this._scrollTime + 64 > Date.now());
}

/**
* @private
*/
getActiveNav(): Nav | Tabs {
var nav = this._rootNav || null;
var activeChildNav;

while (nav) {
activeChildNav = nav.getActiveChildNav();
if (!activeChildNav) {
break;
}
nav = activeChildNav;
}

return nav;
}

/**
* @private
*/
getRootNav(): any {
return this._rootNav;
}

/**
* @private
*/
setRootNav(nav: any) {
this._rootNav = nav;
}

/**
* @private
* Register a known component with a key, for easy lookups later.
Expand Down
112 changes: 112 additions & 0 deletions ionic/components/app/test/app.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import {IonicApp, Nav, Tabs, Tab, NavOptions, Config, ViewController} from '../../../../ionic';

export function run() {


describe('IonicApp', () => {

describe('getActiveNav', () => {

it('should get active NavController when using tabs with nested nav', () => {
let nav = mockNav();
app.setRootNav(nav);

let tabs = mockTabs();
let tab1 = mockTab(tabs);
let tab2 = mockTab(tabs);
nav.registerChildNav(tabs);

tab2.setSelected(true);
let nav2 = mockNav();
let nav3 = mockNav();
let nav4 = mockNav();
tab1.registerChildNav(nav4);
tab2.registerChildNav(nav2);
tab2.registerChildNav(nav3);

expect(app.getActiveNav()).toBe(nav3);
});

it('should get active NavController when using tabs', () => {
let nav = mockNav();
app.setRootNav(nav);

let tabs = mockTabs();
let tab1 = mockTab(tabs);
let tab2 = mockTab(tabs);
let tab3 = mockTab(tabs);
nav.registerChildNav(tabs);

tab2.setSelected(true);

expect(app.getActiveNav()).toBe(tab2);

tab2.setSelected(false);
tab3.setSelected(true);
expect(app.getActiveNav()).toBe(tab3);
});

it('should get active NavController when nested 3 deep', () => {
let nav1 = mockNav();
let nav2 = mockNav();
let nav3 = mockNav();
app.setRootNav(nav1);

nav1.registerChildNav(nav2);
nav2.registerChildNav(nav3);

expect(app.getActiveNav()).toBe(nav3);
});

it('should get active NavController when nested 2 deep', () => {
let nav1 = mockNav();
let nav2 = mockNav();
app.setRootNav(nav1);

nav1.registerChildNav(nav2);
expect(app.getActiveNav()).toBe(nav2);
});

it('should get active NavController when only one nav controller', () => {
let nav = mockNav();
app.setRootNav(nav);
expect(app.getActiveNav()).toBe(nav);
});

it('should set/get the root nav controller', () => {
let nav = mockNav();
app.setRootNav(nav);
expect(app.getRootNav()).toBe(nav);
});

it('should not get an active NavController if there is not root set', () => {
expect(app.getActiveNav()).toBeNull();
expect(app.getRootNav()).toBeNull();
});

});

var app: IonicApp;
var config: Config;

function mockNav(): Nav {
return new Nav(null,null,null,config,null,null,null,null,null,null);
}

function mockTabs(): Tabs {
return new Tabs(null, null, null, config, null, null, null);
}

function mockTab(parentTabs: Tabs): Tab {
return new Tab(parentTabs,null,config,null,null,null,null,null,null);
}

beforeEach(() => {
config = new Config();
app = new IonicApp(config, null);
});

});


}
26 changes: 23 additions & 3 deletions ionic/components/nav/nav-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export class NavController extends Ion {
private _sbGesture: SwipeBackGesture;
private _sbThreshold: number;
private _portal: Portal;
private _children: any[] = [];

protected _sbEnabled: boolean;
protected _ids: number = -1;
Expand Down Expand Up @@ -166,8 +167,8 @@ export class NavController extends Ion {

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

this._sbEnabled = config.getBoolean('swipeBackEnabled') || false;
this._sbThreshold = config.get('swipeBackThreshold') || 40;
this._sbEnabled = config.getBoolean('swipeBackEnabled');
this._sbThreshold = config.getNumber('swipeBackThreshold', 40);

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

Expand Down Expand Up @@ -1322,14 +1323,33 @@ export class NavController extends Ion {
}
}

getActiveChildNav(): any {
return this._children[this._children.length - 1];
}

registerChildNav(nav: any) {
this._children.push(nav);
}

unregisterChildNav(nav: any) {
let index = this._children.indexOf(nav);
if (index > -1) {
this._children.splice(index, 1);
}
}

/**
* @private
*/
ngOnDestroy() {
for (var i = this._views.length - 1; i >= 0; i--) {
this._views[i].destroy();
}
this._views = [];
this._views.length = 0;

if (this.parent) {
this.parent.unregisterChildNav(this);
}
}

/**
Expand Down
13 changes: 11 additions & 2 deletions ionic/components/nav/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export class Nav extends NavController {
private _hasInit: boolean = false;

constructor(
@Optional() hostNavCtrl: NavController,
@Optional() parent: NavController,
@Optional() viewCtrl: ViewController,
app: IonicApp,
config: Config,
Expand All @@ -124,14 +124,23 @@ export class Nav extends NavController {
zone: NgZone,
renderer: Renderer
) {
super(hostNavCtrl, app, config, keyboard, elementRef, 'contents', compiler, viewManager, zone, renderer);
super(parent, app, config, keyboard, elementRef, 'contents', compiler, viewManager, zone, renderer);

if (viewCtrl) {
// an ion-nav can also act as an ion-page within a parent ion-nav
// this would happen when an ion-nav nests a child ion-nav.
viewCtrl.setContent(this);
viewCtrl.setContentRef(elementRef);
}

if (parent) {
// this Nav has a parent Nav
parent.registerChildNav(this);

} else if (app) {
// this is the root navcontroller for the entire app
this._app.setRootNav(this);
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion ionic/components/tabs/tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export class Tab extends NavController {
private _panelId: string;
private _btnId: string;
private _loaded: boolean;
private _loadTmr: number;
private _loadTmr: any;

/**
* @private
Expand Down
18 changes: 17 additions & 1 deletion ionic/components/tabs/tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ export class Tabs extends Ion {
parent: any;

constructor(
@Optional() viewCtrl: ViewController,
@Optional() parent: NavController,
@Optional() viewCtrl: ViewController,
private _app: IonicApp,
private _config: Config,
private _elementRef: ElementRef,
Expand All @@ -149,6 +149,15 @@ export class Tabs extends Ion {
this.subPages = _config.getBoolean('tabSubPages');
this._useHighlight = _config.getBoolean('tabbarHighlight');

if (parent) {
// this Tabs has a parent Nav
parent.registerChildNav(this);

} else if (this._app) {
// this is the root navcontroller for the entire app
this._app.setRootNav(this);
}

// Tabs may also be an actual ViewController which was navigated to
// if Tabs is static and not navigated to within a NavController
// then skip this and don't treat it as it's own ViewController
Expand Down Expand Up @@ -308,6 +317,13 @@ export class Tabs extends Ion {
return null;
}

/**
* @private
*/
getActiveChildNav() {
return this.getSelected();
}

/**
* @private
*/
Expand Down

0 comments on commit 7777237

Please sign in to comment.