This commit is contained in:
Adam Bradley
2015-06-04 16:42:24 -05:00
parent c097a32fbd
commit 02e789649a
4 changed files with 108 additions and 70 deletions

View File

@ -15,6 +15,7 @@ import {NavPane, NavBarSection} from './nav-pane';
import {Transition, ClickBlock} from 'ionic/ionic';
import * as util from 'ionic/util';
let itemsIds = -1;
export class NavBase {
@ -39,6 +40,9 @@ export class NavBase {
this.sbTransition = null;
this.sbActive = false;
this.panes = {};
this.id = ++itemsIds;
this.childIds = -1;
}
initial(initial) {
@ -109,8 +113,8 @@ export class NavBase {
}
}
push(Component, params = {}, opts = {}) {
if (!Component || this.isTransitioning()) {
push(ComponentClass, params = {}, opts = {}) {
if (!ComponentClass || this.isTransitioning()) {
return Promise.reject();
}
@ -136,13 +140,13 @@ export class NavBase {
leavingItem.willCache();
// create a new NavStackItem
let enteringItem = new NavItem(this, Component, params);
let enteringItem = new NavItem(this, ComponentClass, params);
// set that this item is staged (it's not ready to be animated in yet)
enteringItem.state = STAGED_STATE;
// add the item to the stack
this.items.push(enteringItem);
this.add(enteringItem);
// start the transition
this.transition(enteringItem, leavingItem, opts, () => {
@ -193,7 +197,25 @@ export class NavBase {
return promise;
}
switchActive(enteringItem, opts = {}) {
opts.animation = 'none';
let leavingItem = this.getActive() || new NavItem();
leavingItem.shouldDestroy = false;
leavingItem.shouldCache = true;
leavingItem.willCache();
this.transition(enteringItem, leavingItem, opts, () => {
// transition completed, destroy the leaving item
console.log('switchActive comlete')
});
}
transition(enteringItem, leavingItem, opts, callback) {
if (!enteringItem || enteringItem === leavingItem) {
return callback();
}
opts.isAnimated = (opts.animation !== 'none');
this.transitionStart(opts);
@ -409,16 +431,6 @@ export class NavBase {
return false;
}
clear() {
let pops = [];
for(let item of this.items) {
pops.push(this.pop({
animate: false
}));
}
return Promise.all(pops);
}
getActive() {
for (let i = 0, ii = this.items.length; i < ii; i++) {
if (this.items[i].state === ACTIVE_STATE) {
@ -428,6 +440,15 @@ export class NavBase {
return null;
}
findByInstance(instance) {
for (let i = 0, ii = this.items.length; i < ii; i++) {
if (this.items[i].instance === instance) {
return this.items[i];
}
}
return null;
}
getPrevious(item) {
if (item) {
return this.items[ this.items.indexOf(item) - 1 ];
@ -457,10 +478,43 @@ export class NavBase {
return this.domElement;
}
add(item) {
item.id = this.id + '' + (++this.childIds);
this.items.push(item);
}
remove(itemOrIndex) {
util.array.remove(this.items, itemOrIndex);
}
length() {
return this.items.length;
}
isActive(item) {
return (item && item.stage === ACTIVE_STATE);
}
clear() {
let pops = [];
for (let item of this.items) {
pops.push(this.pop({
animate: false
}));
}
return Promise.all(pops);
}
instances() {
let instances = [];
for (let item of this.items) {
if (item.instance) {
instances.push(item.instance);
}
}
return instances
}
width() {
return this.domElement.offsetWidth;
}

View File

@ -11,11 +11,12 @@ import {TabPane, NavPane, NavPaneSection} from './nav';
export class NavItem {
constructor(navBase, Component, params = {}) {
constructor(navBase, ComponentClass, params = {}) {
this.navBase = navBase;
this.Component = Component;
this.ComponentClass = ComponentClass;
this.params = params;
this.id = util.nextUid();
this.instance = null;
this._titleEle = undefined;
this._backBtn = undefined;
this.disposals = [];
@ -40,7 +41,7 @@ export class NavItem {
}
// compile the Component
this.navBase.compiler.compileInHost(this.Component).then(componentProtoViewRef => {
this.navBase.compiler.compileInHost(this.ComponentClass).then(componentProtoViewRef => {
// figure out the sturcture of this Component
// does it have a navbar? Is it tabs? Should it not have a navbar or any toolbars?

View File

@ -50,18 +50,24 @@ export class Tab {
injector: Injector,
viewContainerRef: ViewContainerRef
) {
this.navBase = new NavBase(parentNavBase, compiler, elementRef, loader, injector);
this.parentNavBase = parentNavBase;
this.tabItem = new NavItem(parentNavBase);
this.tabItem.instance = this
tabs.addTab(this.tabItem);
this.panelId = 'tab-panel-' + this.tabItem.id;
this.labeledBy = 'tab-button-' + this.tabItem.id;
this.elementRef = elementRef;
this.viewContainerRef = viewContainerRef;
this.sections = parentNavBase.panes['_n'].sections;
this.navBase.panes['_n'] = this;
this.isSelected = false;
tabs.addTab(this);
this.panelId = 'tab-panel-' + this.id;
this.labeledBy = 'tab-button-' + this.id;
this.domElement = elementRef.domElement;
this.config = Nav.config.invoke(this);
@ -69,19 +75,8 @@ export class Tab {
console.log('Tab constructor', this.id, ' parentNavBase:', parentNavBase);
}
onInit() {
this.navBase.initial(this.initial);
}
select(shouldSelect) {
if (shouldSelect && !this.isSelected) {
console.log('Select tab', this.id);
} else if (!shouldSelect && this.isSelected) {
console.log('Deselect tab', this.id);
}
this.isSelected = shouldSelect;
get isSelected() {
return this.parentNavBase.isActive(this);
}
}

View File

@ -1,8 +1,9 @@
import {Ancestor, Parent} from 'angular2/src/core/annotations_impl/visibility';
import {Optional} from 'angular2/src/di/annotations_impl'
import {Directive, Component, onInit} from 'angular2/src/core/annotations_impl/annotations';
import {Directive, Component} from 'angular2/src/core/annotations_impl/annotations';
import {View} from 'angular2/src/core/annotations_impl/view';
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {Compiler} from 'angular2/angular2';
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
import {Injector} from 'angular2/di';
import {NgFor} from 'angular2/angular2';
@ -14,17 +15,15 @@ import {TabButton} from './tab-button';
import {Icon} from '../icon/icon';
import {Nav, NavPane} from '../nav/nav';
import {NavItem} from '../nav/nav-item';
import {NavBase} from '../nav/nav-base';
let tabsId = -1;
@Component({
selector: 'ion-tabs',
properties: [
'tabBarPlacement',
'tabBarIcons'
],
lifecycle: [onInit]
]
})
@View({
template: `
@ -43,46 +42,35 @@ let tabsId = -1;
directives: [NgFor, TabButton, Icon]
})
export class Tabs {
constructor(elementRef: ElementRef) {
this.id = ++tabsId;
this.tabIds = 0;
this.tabs = [];
this._selected = null;
constructor(
@Optional() parentNavBase: NavBase,
compiler: Compiler,
elementRef: ElementRef,
loader: DynamicComponentLoader,
injector: Injector
) {
this.navBase = new NavBase(parentNavBase, compiler, elementRef, loader, injector);
this.domElement = elementRef.domElement;
this.config = Tabs.config.invoke(this);
console.log('Tabs constructor', this.id);
}
onInit() {
if (this.tabs.length > 0) {
this.selectTab(this.tabs[0]);
addTab(tabItem) {
this.navBase.add(tabItem);
if (this.navBase.length() === 1) {
this.selectTab(tabItem.instance);
}
}
addTab(tab) {
tab.id = this.id + '' + (++this.tabIds);
this.tabs.push(tab);
get tabs() {
return this.navBase.instances();
}
selectTab(tabToSelect) {
if (typeof tabToSelect === 'number') {
let index = tabToSelect;
tabToSelect = null;
if (index < this.tabs.length) {
tabToSelect = this.tabs[index];
}
}
if (!tabToSelect || this._selected === tabToSelect) return;
selectTab(tabInstance) {
let enteringItem = this.navBase.findByInstance(tabInstance);
let tabToDeselect = this._selected;
this.tabs.forEach(tab => {
tab.select( (tab === tabToSelect) );
});
this._selected = tabToSelect;
this.navBase.switchActive(enteringItem);
}
}