mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(tabs): track tab selecting history, create previousTab() method
This commit is contained in:
@@ -138,7 +138,7 @@ import {ViewController} from '../nav/view-controller';
|
||||
'</ion-navbar-section>' +
|
||||
'<ion-tabbar-section>' +
|
||||
'<tabbar role="tablist">' +
|
||||
'<a *ngFor="let t of _tabs" [tab]="t" class="tab-button" [class.tab-disabled]="!t.enabled" [class.tab-hidden]="!t.show" role="tab" href="#">' +
|
||||
'<a *ngFor="let t of _tabs" [tab]="t" class="tab-button" [class.tab-disabled]="!t.enabled" [class.tab-hidden]="!t.show" role="tab" href="#" (ionSelect)="select($event)">' +
|
||||
'<ion-icon *ngIf="t.tabIcon" [name]="t.tabIcon" [isActive]="t.isSelected" class="tab-button-icon"></ion-icon>' +
|
||||
'<span *ngIf="t.tabTitle" class="tab-button-text">{{t.tabTitle}}</span>' +
|
||||
'<ion-badge *ngIf="t.tabBadge" class="tab-badge" [ngClass]="\'badge-\' + t.tabBadgeStyle">{{t.tabBadge}}</ion-badge>' +
|
||||
@@ -175,6 +175,11 @@ export class Tabs extends Ion {
|
||||
*/
|
||||
navbarContainerRef: ViewContainerRef;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
selectHistory: string[] = [];
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -213,12 +218,7 @@ export class Tabs extends Ion {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@ViewChildren(TabButton) private _btns: any;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
parent: any;
|
||||
parent: NavController;
|
||||
|
||||
constructor(
|
||||
@Optional() parent: NavController,
|
||||
@@ -271,12 +271,6 @@ export class Tabs extends Ion {
|
||||
});
|
||||
}
|
||||
|
||||
this._btns.toArray().forEach((tabButton: TabButton) => {
|
||||
tabButton.ionSelect.subscribe((tab: Tab) => {
|
||||
this.select(tab);
|
||||
});
|
||||
});
|
||||
|
||||
let preloadTabs = (isBlank(this.preloadTabs) ? this._config.getBoolean('preloadTabs') : isTrueProperty(this.preloadTabs));
|
||||
|
||||
// get the selected index
|
||||
@@ -333,11 +327,11 @@ export class Tabs extends Ion {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} index Index of the tab you want to select
|
||||
* @param {number|Tab} tabOrIndex Index, or the Tab instance, of the tab to select.
|
||||
*/
|
||||
select(tabOrIndex: any) {
|
||||
let selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex);
|
||||
if (!selectedTab) {
|
||||
select(tabOrIndex: number | Tab) {
|
||||
let selectedTab: Tab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex);
|
||||
if (isBlank(selectedTab)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -390,9 +384,37 @@ export class Tabs extends Ion {
|
||||
this._onReady = null;
|
||||
}
|
||||
|
||||
// track the order of which tabs have been selected, by their index
|
||||
// do not track if the tab index is the same as the previous
|
||||
if (this.selectHistory[this.selectHistory.length - 1] !== selectedTab.id) {
|
||||
this.selectHistory.push(selectedTab.id);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the previously selected Tab which is currently not disabled or hidden.
|
||||
* @param {boolean} trimHistory If the selection history should be trimmed up to the previous tab selection or not.
|
||||
* @returns {Tab}
|
||||
*/
|
||||
previousTab(trimHistory: boolean = true): Tab {
|
||||
// walk backwards through the tab selection history
|
||||
// and find the first previous tab that is enabled and shown
|
||||
console.log('run previousTab', this.selectHistory)
|
||||
for (var i = this.selectHistory.length - 2; i >= 0; i--) {
|
||||
var tab = this._tabs.find(t => t.id === this.selectHistory[i]);
|
||||
if (tab && tab.enabled && tab.show) {
|
||||
if (trimHistory) {
|
||||
this.selectHistory.splice(i + 1);
|
||||
}
|
||||
return tab;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} index Index of the tab you want to get
|
||||
* @returns {Tab} Returns the tab who's index matches the one passed
|
||||
|
||||
212
src/components/tabs/test/tabs.spec.ts
Normal file
212
src/components/tabs/test/tabs.spec.ts
Normal file
@@ -0,0 +1,212 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {App, Nav, Tabs, Tab, NavOptions, Config, ViewController, Platform} from '../../../../src';
|
||||
|
||||
export function run() {
|
||||
|
||||
describe('Tabs', () => {
|
||||
|
||||
describe('previousTab', () => {
|
||||
|
||||
it('should find the previous tab when there has been 3 selections', () => {
|
||||
var tabs = mockTabs();
|
||||
var tab0 = mockTab(tabs);
|
||||
var tab1 = mockTab(tabs);
|
||||
var tab2 = mockTab(tabs);
|
||||
tabs.add(tab0);
|
||||
tabs.add(tab1);
|
||||
tabs.add(tab2);
|
||||
tab0.root = SomePage;
|
||||
tab1.root = SomePage;
|
||||
tab2.root = SomePage;
|
||||
|
||||
tabs.select(tab0);
|
||||
tabs.select(tab1);
|
||||
tabs.select(tab2);
|
||||
|
||||
expect(tabs.selectHistory).toEqual([tab0.id, tab1.id, tab2.id]);
|
||||
|
||||
expect(tabs.previousTab(true)).toEqual(tab1);
|
||||
expect(tabs.selectHistory).toEqual([tab0.id, tab1.id]);
|
||||
|
||||
expect(tabs.previousTab(true)).toEqual(tab0);
|
||||
expect(tabs.selectHistory).toEqual([tab0.id]);
|
||||
});
|
||||
|
||||
it('should not find a previous tab when there has only been one selection', () => {
|
||||
var tabs = mockTabs();
|
||||
var tab0 = mockTab(tabs);
|
||||
var tab1 = mockTab(tabs);
|
||||
tabs.add(tab0);
|
||||
tabs.add(tab1);
|
||||
tab0.root = SomePage;
|
||||
tab1.root = SomePage;
|
||||
|
||||
tabs.select(tab0);
|
||||
|
||||
expect(tabs.previousTab(true)).toEqual(null);
|
||||
});
|
||||
|
||||
it('should not find a previous tab when theres no history', () => {
|
||||
var tabs = mockTabs();
|
||||
expect(tabs.selectHistory.length).toEqual(0);
|
||||
expect(tabs.previousTab(true)).toEqual(null);
|
||||
});
|
||||
|
||||
it('should track tab selections', () => {
|
||||
var tabs = mockTabs();
|
||||
var tab0 = mockTab(tabs);
|
||||
var tab1 = mockTab(tabs);
|
||||
tabs.add(tab0);
|
||||
tabs.add(tab1);
|
||||
tab0.root = SomePage;
|
||||
tab1.root = SomePage;
|
||||
|
||||
expect(tabs.selectHistory.length).toEqual(0);
|
||||
|
||||
tabs.select(tab0);
|
||||
expect(tabs.selectHistory[0]).toEqual(tab0.id);
|
||||
expect(tabs.selectHistory.length).toEqual(1);
|
||||
|
||||
tabs.select(tab1);
|
||||
expect(tabs.selectHistory[0]).toEqual(tab0.id);
|
||||
expect(tabs.selectHistory[1]).toEqual(tab1.id);
|
||||
expect(tabs.selectHistory.length).toEqual(2);
|
||||
|
||||
tabs.select(tab0);
|
||||
expect(tabs.selectHistory[0]).toEqual(tab0.id);
|
||||
expect(tabs.selectHistory[1]).toEqual(tab1.id);
|
||||
expect(tabs.selectHistory[2]).toEqual(tab0.id);
|
||||
expect(tabs.selectHistory.length).toEqual(3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('select', () => {
|
||||
|
||||
it('should select tab by tab instance', () => {
|
||||
var tabs = mockTabs();
|
||||
var tab0 = mockTab(tabs);
|
||||
var tab1 = mockTab(tabs);
|
||||
tabs.add(tab0);
|
||||
tabs.add(tab1);
|
||||
|
||||
tab0.root = SomePage;
|
||||
tab1.root = SomePage;
|
||||
|
||||
tabs.select(tab1);
|
||||
|
||||
expect(tab0.isSelected).toEqual(false);
|
||||
expect(tab1.isSelected).toEqual(true);
|
||||
});
|
||||
|
||||
it('should select tab by index', () => {
|
||||
var tabs = mockTabs();
|
||||
var tab0 = mockTab(tabs);
|
||||
var tab1 = mockTab(tabs);
|
||||
tabs.add(tab0);
|
||||
tabs.add(tab1);
|
||||
|
||||
tab0.root = SomePage;
|
||||
tab1.root = SomePage;
|
||||
|
||||
expect(tab0.isSelected).toBeUndefined();
|
||||
expect(tab1.isSelected).toBeUndefined();
|
||||
|
||||
tabs.select(0);
|
||||
|
||||
expect(tab0.isSelected).toEqual(true);
|
||||
expect(tab1.isSelected).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not select an invalid tab index', () => {
|
||||
var tabs = mockTabs();
|
||||
var tab0 = mockTab(tabs);
|
||||
var tab1 = mockTab(tabs);
|
||||
tabs.add(tab0);
|
||||
tabs.add(tab1);
|
||||
|
||||
expect(tabs.select(22)).toBeUndefined();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('getByIndex', () => {
|
||||
|
||||
it('should get the tab', () => {
|
||||
var tabs = mockTabs();
|
||||
var tab0 = mockTab(tabs);
|
||||
tab0.setRoot()
|
||||
var tab1 = mockTab(tabs);
|
||||
tabs.add(tab0);
|
||||
tabs.add(tab1);
|
||||
|
||||
expect(tabs.getIndex(tab0)).toEqual(0);
|
||||
expect(tabs.getIndex(tab1)).toEqual(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('getSelected', () => {
|
||||
|
||||
it('should get the selected tab', () => {
|
||||
var tabs = mockTabs();
|
||||
var tab0 = mockTab(tabs);
|
||||
var tab1 = mockTab(tabs);
|
||||
tabs.add(tab0);
|
||||
tabs.add(tab1);
|
||||
|
||||
tab1.setSelected(true);
|
||||
|
||||
expect(tabs.getSelected()).toEqual(tab1);
|
||||
});
|
||||
|
||||
it('should get null if no selected tab', () => {
|
||||
var tabs = mockTabs();
|
||||
var tab0 = mockTab(tabs);
|
||||
var tab1 = mockTab(tabs);
|
||||
tabs.add(tab0);
|
||||
tabs.add(tab1);
|
||||
|
||||
expect(tabs.getSelected()).toEqual(null);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
var app: App;
|
||||
var config: Config;
|
||||
var platform: Platform;
|
||||
var _cd: any;
|
||||
|
||||
function mockNav(): Nav {
|
||||
return new Nav(null, null, null, config, null, null, null, null, null);
|
||||
}
|
||||
|
||||
function mockTabs(): Tabs {
|
||||
return new Tabs(null, null, null, config, null, null, null);
|
||||
}
|
||||
|
||||
function mockTab(parentTabs: Tabs): Tab {
|
||||
var tab = new Tab(parentTabs, app, config, null, null, null, null, null, _cd);
|
||||
tab.load = function(opts: any, cb: Function) {
|
||||
cb();
|
||||
};
|
||||
return tab;
|
||||
}
|
||||
|
||||
@Component({})
|
||||
class SomePage {}
|
||||
|
||||
beforeEach(() => {
|
||||
config = new Config();
|
||||
platform = new Platform();
|
||||
app = new App(config, null, platform);
|
||||
_cd = {
|
||||
reattach: function(){},
|
||||
detach: function(){}
|
||||
};
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user