pane pain

This commit is contained in:
Adam Bradley
2015-06-10 09:11:57 -05:00
parent 7aea8d5b61
commit 053c4ce238
9 changed files with 114 additions and 101 deletions

View File

@@ -39,7 +39,7 @@ export class BackButton {
ev.preventDefault();
let item = this.item;
item && item.viewController && item.viewController.pop();
item && item.viewCtrl && item.viewCtrl.pop();
}
}

View File

@@ -4,10 +4,9 @@ import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {ProtoViewRef} from 'angular2/src/core/compiler/view_ref';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import * as dom from '../../util/dom';
import {Platform} from 'ionic/platform/platform';
import {ViewItem} from '../view/view-item';
import {BackButton} from './back-button';
import * as dom from '../../util/dom';
@Component({
@@ -34,7 +33,7 @@ import {BackButton} from './back-button';
lifecycle: [onInit]
})
export class Navbar {
constructor(item: ViewItem, elementRef:ElementRef, ngZone:NgZone) {
constructor(item: ViewItem, elementRef: ElementRef, ngZone: NgZone) {
this.item = item;
this.domElement = elementRef.domElement;
this.zone = ngZone;

View File

@@ -20,13 +20,13 @@ import {ViewController} from '../view/view-controller';
export class Nav extends ViewController {
constructor(
@Optional() viewController: ViewController,
@Optional() viewCtrl: ViewController,
compiler: Compiler,
elementRef: ElementRef,
loader: DynamicComponentLoader,
injector: Injector
) {
super(viewController, compiler, elementRef, loader, injector);
super(viewCtrl, compiler, elementRef, loader, injector);
this.panes.setAnchor(elementRef);
}

View File

@@ -1,4 +1,4 @@
import {Component, Directive, onInit} from 'angular2/src/core/annotations_impl/annotations';
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
import {View} from 'angular2/src/core/annotations_impl/view';
import {Parent} from 'angular2/src/core/annotations_impl/visibility';
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
@@ -6,15 +6,14 @@ import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {bind} from 'angular2/di';
import {ViewController} from '../view/view-controller';
import {Nav} from './nav';
import {SwipeHandle} from './swipe-handle';
import {ModeComponent} from '../../config/component';
export class PaneController {
constructor(viewController: ViewController) {
constructor(viewCtrl: ViewController) {
this.panes = {};
this.viewController = viewController;
this.viewCtrl = viewCtrl;
}
get(itemStructure, callback) {
@@ -23,7 +22,7 @@ export class PaneController {
// Tabs and view's without a navbar would get a different Panes
let key = itemStructure.key;
let viewController = this.viewController;
let viewCtrl = this.viewCtrl;
let pane = this.panes[key];
if (pane) {
@@ -34,13 +33,13 @@ export class PaneController {
// create a new nav pane
this.panes[key] = null;
let injector = viewController.injector.resolveAndCreateChild([
bind(ViewController).toValue(viewController)
let injector = viewCtrl.injector.resolveAndCreateChild([
bind(ViewController).toValue(viewCtrl)
]);
// add a Pane element
// when the Pane is added, it'll also add its reference to the panes object
viewController.loader.loadNextToExistingLocation(Pane, this.anchor, injector).then(() => {
viewCtrl.loader.loadNextToExistingLocation(Pane, this.anchor, injector).then(() => {
// get the pane reference by name
pane = this.panes[key];
@@ -63,7 +62,7 @@ export class PaneController {
// as each section is compiled and added to the Pane
// the section will add a reference to itself in the Pane's sections object
promises.push(
viewController.loader.loadNextToExistingLocation(SectionClass, sectionAnchorElementRef)
viewCtrl.loader.loadNextToExistingLocation(SectionClass, sectionAnchorElementRef)
);
});
@@ -88,7 +87,6 @@ export class PaneController {
return;
}
}
this.panes['_n'] = pane;
}
}
@@ -108,13 +106,8 @@ export class PaneController {
directives: [PaneAnchor, PaneContentAnchor, SwipeHandle]
})
class Pane {
constructor(@Parent() nav: Nav, viewContainerRef: ViewContainerRef) {
this.sections = {};
nav.panes.add(this);
}
addSection(sectionName, instance) {
this.sections[sectionName] = instance;
constructor(viewCtrl: ViewController) {
viewCtrl.panes.add(this);
}
}
@@ -152,7 +145,7 @@ class NavBarContainer {}
selector: 'template[navbar-anchor]'
})
class NavBarAnchor {
constructor(viewController: ViewController, viewContainerRef: ViewContainerRef) {
viewController.navbarViewContainer(viewContainerRef);
constructor(viewCtrl: ViewController, viewContainerRef: ViewContainerRef) {
viewCtrl.navbarViewContainer(viewContainerRef);
}
}

View File

@@ -14,12 +14,12 @@ import {Gesture} from 'ionic/gestures/gesture';
})
export class SwipeHandle {
constructor(
@Optional() viewController: ViewController,
@Optional() viewCtrl: ViewController,
elementRef: ElementRef
) {
if (!viewController) return;
if (!viewCtrl) return;
this.viewController = viewController;
this.viewCtrl = viewCtrl;
let gesture = new Gesture(elementRef.domElement);
gesture.listen();
@@ -62,7 +62,7 @@ export class SwipeHandle {
}
}
viewController.swipeBackEnd(completeSwipeBack, progress, playbackRate);
viewCtrl.swipeBackEnd(completeSwipeBack, progress, playbackRate);
startX = null;
}
@@ -73,18 +73,18 @@ export class SwipeHandle {
ev.stopPropagation();
startX = ev.gesture.center.x;
swipeableAreaWidth = viewController.width() - startX;
swipeableAreaWidth = viewCtrl.width() - startX;
viewController.swipeBackStart();
viewCtrl.swipeBackStart();
}
viewController.swipeBackProgress( (ev.gesture.center.x - startX) / swipeableAreaWidth );
viewCtrl.swipeBackProgress( (ev.gesture.center.x - startX) / swipeableAreaWidth );
}
}
showHandle() {
return (this.viewController ? this.viewController.swipeBackEnabled() : false);
return (this.viewCtrl ? this.viewCtrl.swipeBackEnabled() : false);
}
}

View File

@@ -6,7 +6,6 @@ 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 {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
import {ViewController} from '../view/view-controller';
import {Tabs} from './tabs';
@@ -34,10 +33,10 @@ import {IonicComponent} from '../../config/component';
})
@View({
template: `
<template content-anchor></template>
<template pane-anchor></template>
<content></content>
`,
directives: [TabContentAnchor]
directives: [TabPaneAnchor]
})
export class Tab extends ViewController {
@@ -46,17 +45,21 @@ export class Tab extends ViewController {
compiler: Compiler,
elementRef: ElementRef,
loader: DynamicComponentLoader,
injector: Injector,
viewContainerRef: ViewContainerRef
injector: Injector
) {
// A Tab is both a container of many views, and is a view itself.
// A Tab is one ViewItem within it's parent Tabs (which extends ViewController)
// A Tab is a ViewController for its child ViewItems
super(tabs, compiler, elementRef, loader, injector);
this.tabs = tabs;
// the navbar is already provided by the container of Tabs, which contains Tab
// Views which come into this Tab should not create their own navbar, but use the parent's
this.parentNavbar(true);
let item = this.item = new ViewItem(tabs.parent);
item.setInstance(this);
item.setViewElement(elementRef.domElement);
this.panes.add(this)
tabs.addTab(this.item);
this.panelId = 'tab-panel-' + item.id;
@@ -93,10 +96,10 @@ export class Tab extends ViewController {
@Directive({
selector: 'template[content-anchor]'
selector: 'template[pane-anchor]'
})
class TabContentAnchor {
constructor(@Parent() tab: Tab, viewContainerRef: ViewContainerRef) {
tab.contentContainerRef = viewContainerRef;
class TabPaneAnchor {
constructor(@Parent() tab: Tab, elementRef: ElementRef) {
tab.panes.setAnchor(elementRef);
}
}

View File

@@ -1,13 +1,11 @@
import {Ancestor, Parent} from 'angular2/src/core/annotations_impl/visibility';
import {Optional} from 'angular2/src/di/annotations_impl'
import {Directive, Component} from 'angular2/src/core/annotations_impl/annotations';
import {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';
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
import {ViewController} from '../view/view-controller';
import {ViewItem} from '../view/view-item';
@@ -44,14 +42,14 @@ import {ModeComponent} from '../../config/component';
export class Tabs extends ViewController {
constructor(
@Optional() viewController: ViewController,
@Optional() viewCtrl: ViewController,
@Optional() item: ViewItem,
compiler: Compiler,
elementRef: ElementRef,
loader: DynamicComponentLoader,
injector: Injector
) {
super(viewController, compiler, elementRef, loader, injector);
super(viewCtrl, compiler, elementRef, loader, injector);
this.item = item;
}

View File

@@ -21,14 +21,14 @@ import * as util from 'ionic/util';
export class ViewController {
constructor(
parent: ViewController,
parentViewCtrl: ViewController,
compiler: Compiler,
elementRef: ElementRef,
loader: DynamicComponentLoader,
injector: Injector
) {
this.parent = parent;
this.parent = parentViewCtrl;
this.compiler = compiler;
this.elementRef = elementRef;
this.loader = loader;
@@ -420,6 +420,13 @@ export class ViewController {
}
}
parentNavbar() {
if (arguments.length) {
this._parentNavbar = arguments[0];
}
return this._parentNavbar;
}
add(item) {
item.id = this.id + '' + (++this.childIds);
this.items.push(item);

View File

@@ -9,8 +9,8 @@ import {NavParams} from '../nav/nav-params';
export class ViewItem {
constructor(viewController, ComponentClass, params = {}) {
this.viewController = viewController;
constructor(viewCtrl, ComponentClass, params = {}) {
this.viewCtrl = viewCtrl;
this.ComponentClass = ComponentClass;
this.params = new NavParams(params);
this.instance = null;
@@ -31,45 +31,47 @@ export class ViewItem {
}
stage(callback) {
let viewController = this.viewController;
let viewCtrl = this.viewCtrl;
// update if it's possible to go back from this nav item
this.enableBack = viewController && !!viewController.getPrevious(this);
this.enableBack = viewCtrl && !!viewCtrl.getPrevious(this);
if (this.instance || !viewController) {
if (this.instance || !viewCtrl) {
// already compiled this view
return callback();
}
// compile the Component
viewController.compiler.compileInHost(this.ComponentClass).then(componentProtoViewRef => {
viewCtrl.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?
let itemStructure = getProtoViewStructure(componentProtoViewRef);
let itemStructure = this.sturcture = this.getProtoViewStructure(componentProtoViewRef);
console.log('Pane itemStructure', itemStructure.key);
// get the appropriate Pane which this ViewItem will fit into
viewController.panes.get(itemStructure, pane => {
viewCtrl.panes.get(itemStructure, pane => {
// create a new injector just for this ViewItem
let injector = viewController.injector.resolveAndCreateChild([
bind(ViewController).toValue(viewController),
bind(NavController).toValue(viewController.navCtrl),
let injector = viewCtrl.injector.resolveAndCreateChild([
bind(ViewController).toValue(viewCtrl),
bind(NavController).toValue(viewCtrl.navCtrl),
bind(NavParams).toValue(this.params),
bind(ViewItem).toValue(this)
]);
// add the content of the view to the content area
let viewContainer = pane.contentContainerRef;
let hostViewRef = viewContainer.create(componentProtoViewRef, -1, null, injector);
// it will already have the correct context
let contentContainer = pane.contentContainerRef;
let hostViewRef = contentContainer.create(componentProtoViewRef, -1, null, injector);
let newLocation = new ElementRef(hostViewRef, 0);
this.setInstance( viewController.loader._viewManager.getComponent(newLocation) );
// get the component's instance, and set it to the this ViewItem
this.setInstance( viewCtrl.loader._viewManager.getComponent(new ElementRef(hostViewRef, 0)) );
this.setViewElement( hostViewRef._view.render._view.rootNodes[0] );
// remember how to dispose of this reference
this.disposals.push(() => {
viewContainer.remove( viewContainer.indexOf(hostViewRef) );
contentContainer.remove( contentContainer.indexOf(hostViewRef) );
});
// get the view's context so when creating the navbar
@@ -82,7 +84,7 @@ export class ViewItem {
};
// get the item container's nav bar
let navbarViewContainer = viewController.navbarViewContainer();
let navbarViewContainer = viewCtrl.navbarViewContainer();
// get the item's navbar protoview
let navbarProtoView = this.protos.navbar;
@@ -113,6 +115,47 @@ export class ViewItem {
});
}
getProtoViewStructure(componentProtoViewRef) {
let navbar = false;
let tabs = false;
let toolbars = [];
let key = '';
componentProtoViewRef._protoView.elementBinders.forEach(rootElementBinder => {
if (!rootElementBinder.componentDirective || !rootElementBinder.nestedProtoView) return;
rootElementBinder.nestedProtoView.elementBinders.forEach(nestedElementBinder => {
if ( isComponent(nestedElementBinder, 'Tabs') ) {
navbar = true;
}
if (!nestedElementBinder.componentDirective && nestedElementBinder.nestedProtoView) {
nestedElementBinder.nestedProtoView.elementBinders.forEach(templatedElementBinder => {
if ( isComponent(templatedElementBinder, 'Navbar') ) {
navbar = true;
}
});
}
});
});
console.log('getProtoViewStructure')
if (this.viewCtrl.parentNavbar()) {
navbar = false;
}
if (navbar) key += 'n'
if (tabs) key += 't'
key += 'b' + toolbars.length;
return {
navbar,
tabs,
toolbars,
key
};
}
waitForResolve() {
this._wait = true;
}
@@ -269,36 +312,6 @@ export class ViewItem {
}
function getProtoViewStructure(componentProtoViewRef) {
let navbar = true;
let tabs = false;
let toolbars = [];
let key = '_';
// componentProtoViewRef._protoView.elementBinders.forEach(rootElementBinder => {
// if (!rootElementBinder.componentDirective || !rootElementBinder.nestedProtoView) return;
// rootElementBinder.nestedProtoView.elementBinders.forEach(nestedElementBinder => {
// let componentDirective = nestedElementBinder.componentDirective;
// if (componentDirective && componentDirective.metadata.id == 'Tab') {
// navbar = tabs = true;
// }
// });
// });
if (navbar) {
key += 'n'
}
if (toolbars.length) {
key += 'b' + toolbars.length;
}
return {
navbar: navbar,
tabs: tabs,
toolbars: toolbars,
key: key
};
function isComponent(elementBinder, id) {
return (elementBinder && elementBinder.componentDirective && elementBinder.componentDirective.metadata.id == id);
}