diff --git a/ionic/components/nav/nav-controller.ts b/ionic/components/nav/nav-controller.ts index 83a88b6a3a..16254f9826 100644 --- a/ionic/components/nav/nav-controller.ts +++ b/ionic/components/nav/nav-controller.ts @@ -180,6 +180,61 @@ export class NavController extends Ion { this.views.splice(index, 0, viewCtrl); } + /** + * Pop to a specific view in the history stack + * + * @param view {Component} to pop to + * @param opts {object} pop options + */ + popTo(view, opts = {}) { + + // Get the target index of the view to pop to + let viewIndex = this.views.indexOf(view); + let targetIndex = viewIndex + 1; + let resolve; + let promise = new Promise(res => { resolve = res; }); + // Don't pop to the view if it wasn't found, or the target is beyond the view list + if(viewIndex < 0 || targetIndex > this.views.length - 1) { + resolve(); + return; + } + + + opts.direction = opts.direction || 'back'; + + // get the views to auto remove without having to do a transiton for each + // the last view (the currently active one) will do a normal transition out + if (this.views.length > 1) { + let autoRemoveItems = this.views.slice(targetIndex, this.views.length); + for (let i = 0; i < autoRemoveItems.length; i++) { + autoRemoveItems[i].shouldDestroy = true; + autoRemoveItems[i].shouldCache = false; + autoRemoveItems[i].willUnload(); + } + } + + let leavingView = this.views[this.views.length - 1]; + let enteringView = view; + + if(this.router) { + this.router.stateChange('pop', enteringView); + } + + this.transition(enteringView, leavingView, opts, () => { + resolve(); + }); + + return promise; + } + + /** + * Pop to the root view. + * @param opts extra animation options + */ + popToRoot(opts = {}) { + this.popTo(this.views[0]); + } + /** * Set the view stack to reflect the given component classes. * @param {TODO} components TODO diff --git a/ionic/components/tabs/tabs.ts b/ionic/components/tabs/tabs.ts index a2ed163e71..58b6255efb 100644 --- a/ionic/components/tabs/tabs.ts +++ b/ionic/components/tabs/tabs.ts @@ -126,6 +126,12 @@ export class Tabs extends NavController { enteringView = this.getByInstance(tab) } + // If we select the same tab as the active one, do some magic. + if(enteringView === this.getActive()) { + this._touchActive(tab); + return; + } + if (!enteringView || !enteringView.instance || !this.app.isEnabled()) { return Promise.reject(); } @@ -149,6 +155,19 @@ export class Tabs extends NavController { }); } + /** + * "Touch" the active tab, either going back to the root view of the tab + * or scrolling the tab to the top + */ + _touchActive(tab) { + let stateLen = tab.length(); + + if(stateLen > 1) { + // Pop to the root view + tab.popToRoot(); + } + } + get tabs() { return this.instances(); }