overhaul ion-views

This commit is contained in:
Adam Bradley
2015-05-27 11:54:57 -05:00
parent 99aa1c1321
commit 6a349baee7
15 changed files with 105 additions and 237 deletions

View File

@@ -25,7 +25,6 @@ ion-app {
}
ion-nav {
// container of header.toolbar-container, footer.toolbar-container and .nav-item-container
position: absolute;
top: 0;
right: 0;
@@ -33,75 +32,49 @@ ion-nav {
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.toolbar-container {
// container of many toolbars for each view in the ion-nav
position: relative;
ion-view {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
// by default this is display: none;
// and the transition animation will display it
display: none;
flex-direction: column;
&.show-view {
display: flex;
}
}
ion-toolbar {
display: flex;
min-height: 4.4rem;
order: $flex-order-toolbar-top;
}
footer.toolbar-container {
.stage-off {
transform: translateX(9999px);
}
ion-toolbar[footer] {
order: $flex-order-toolbar-bottom;
}
ion-toolbar {
// one view's toolbar, sibling to many view toolbars inside of .toolbar-container
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.nav-item-container {
// container of many .nav-item's, each one containing one view
position: relative;
flex: 1;
order: $flex-order-view-content;
}
.tab-item-container {
// container of each content for each tab component within a tabs component
position: relative;
flex: 1;
order: $flex-order-view-content;
}
.nav-item {
// user created view, sibling to many .nav-item's, contained by .nav-item-container
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
// by default .nav-item is hidden
// and the transition animation will display it
display: none;
&.show-nav-item {
display: block;
}
}
ion-content {
// content within the user created view, contained by .nav-item
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
position: relative;
display: block;
flex: 1;
order: $flex-order-view-content;
}
.scroll-content {
// extra div to allow overflow scrolling
// extra div added by ion-content directive to allow for overflow scrolling
position: absolute;
top: 0;
right: 0;

View File

@@ -265,15 +265,15 @@ export class NavBase {
cleanup() {
this.items.forEach((item) => {
if (item && item.shouldDestroy) {
this.remove(item);
util.dom.raf(() => {
if (item) {
if (item.shouldDestroy) {
this.remove(item);
item.destroy();
});
}
} else if(item.state !== ACTIVE_STATE) {
item.cache();
}
}
});
}

View File

@@ -3,6 +3,9 @@ import {bind} from 'angular2/di';
import * as util from 'ionic/util';
import {NavController} from './nav-controller';
import {NavView} from './nav-view';
const SHOW_VIEW_CSS = 'show-view';
export class NavItem {
@@ -15,7 +18,6 @@ export class NavItem {
this.headerProtos = [];
this.toolbarViews = [];
this._titleEle = undefined;
this.disposals = [];
// if it's possible to go back from this nav item
this.enableBack = false;
@@ -25,13 +27,19 @@ export class NavItem {
// update if it's possible to go back from this nav item
this.enableBack = !!this.nav.getPrevious(this);
if (!this.created) {
return this.create();
}
return Promise.resolve();
return this.create().then(() => {
return new Promise(resolve => {
this.viewEle && this.viewEle.classList.add(SHOW_VIEW_CSS);
resolve();
});
});
}
create() {
if (this.created) {
return Promise.resolve();
}
this.created = true;
let resolve;
@@ -43,30 +51,16 @@ export class NavItem {
bind(NavItem).toValue(this)
]);
this.nav.loader.loadNextToExistingLocation(this.Component, this.nav.contentElementRef, injector).then((componentRef) => {
this.nav.loader.loadNextToExistingLocation(this.Component, this.nav.viewElementRef, injector).then((componentRef) => {
// content
this.component = componentRef;
this.contentEle = componentRef.location.domElement;
this.contentEle.classList.add('nav-item');
this.contentEle.setAttribute('id', 'nav-item-' + this.id);
this.viewEle = componentRef.location.domElement;
this.viewEle.setAttribute('id', 'view-' + this.id);
if (componentRef && componentRef._dispose) {
this.disposals.push(componentRef._dispose);
}
// TODO: talk to misko about correct way to set context
let context = {
boundElementIndex: 0,
parentView: {
_view: componentRef.location.parentView._view.componentChildViews[0]
}
};
for (let i = 0; i < this.headerProtos.length; i++) {
this.createHeader(this.headerProtos[i], context, injector);
if (componentRef && componentRef.dispose) {
this._dispose = componentRef.dispose;
}
resolve();
@@ -75,44 +69,21 @@ export class NavItem {
return promise;
}
createHeader(toolbarProtoView, context, injector) {
let headerContainer = this.nav.headerContainerRef;
if (!headerContainer) return;
let atIndex = -1;
let headerView = headerContainer.create(toolbarProtoView, atIndex, context, injector);
if (headerView) {
this.toolbarViews.push(headerView);
this.disposals.push(() => {
headerContainer.remove( headerContainer.indexOf(headerView) );
});
}
viewElement() {
return this.viewEle;
}
addHeader(toolbarProtoView) {
this.headerProtos.push(toolbarProtoView);
contentElement() {
return this.viewEle.querySelector('ion-content');
}
getContent() {
return this.contentEle;
toolbarElements() {
return this.viewEle.querySelectorAll('ion-toolbar');
}
getToolbars() {
let elements = [];
for (let i = 0; i < this.toolbarViews.length; i++) {
var toolbarView = this.toolbarViews[i];
elements.push(toolbarView._view.render._view.rootNodes[0]);
}
return elements;
}
getTitle() {
titleElement() {
if (this._titleEle === undefined) {
let toolbarElements = this.getToolbars();
let toolbarElements = this.toolbarElements();
for (let i = 0; i < toolbarElements.length; i++) {
var titleEle = toolbarElements[i].querySelector('ion-title');
if (titleEle) {
@@ -125,9 +96,9 @@ export class NavItem {
return this._titleEle;
}
getBackButton() {
backButtonElement() {
if (this._backBtn === undefined) {
let toolbarElements = this.getToolbars();
let toolbarElements = this.toolbarElements();
for (let i = 0; i < toolbarElements.length; i++) {
var backBtn = toolbarElements[i].querySelector('back-button');
if (backBtn) {
@@ -140,10 +111,12 @@ export class NavItem {
return this._backBtn;
}
cache() {
this.viewEle.classList.remove(SHOW_VIEW_CSS);
}
destroy() {
for (let i = 0; i < this.disposals.length; i++) {
this.disposals[i]();
}
this._dispose && this._dispose();
// just to help prevent any possible memory leaks
for (let name in this) {

View File

@@ -17,15 +17,8 @@ import {ToolbarContainer} from '../toolbar/toolbar-container';
}
})
@View({
template: `
<header class="toolbar-container">
<template header-anchor></template>
</header>
<section class="nav-item-container">
<template content-anchor></template>
</section>
`,
directives: [HeaderAnchor, ContentAnchor, ToolbarContainer]
template: `<template view-anchor></template>`,
directives: [ViewAnchor]
})
export class Nav extends NavBase {
constructor(elementRef: ElementRef, loader: DynamicComponentLoader, injector: Injector) {
@@ -40,20 +33,10 @@ export class Nav extends NavBase {
@Directive({
selector: '[header-anchor]'
selector: '[view-anchor]'
})
class HeaderAnchor {
constructor(@Ancestor() nav: Nav, viewContainerRef: ViewContainerRef) {
nav.headerContainerRef = viewContainerRef;
}
}
@Directive({
selector: '[content-anchor]'
})
class ContentAnchor {
class ViewAnchor {
constructor(@Ancestor() nav: Nav, elementRef: ElementRef) {
nav.contentElementRef = elementRef;
nav.viewElementRef = elementRef;
}
}

View File

@@ -1,6 +1,5 @@
<ion-toolbar *header><ion-title>First Page: {{ val }}</ion-title></ion-toolbar>
<ion-toolbar><ion-title>First Page: {{ val }}</ion-title></ion-toolbar>
<ion-content class="padding">

View File

@@ -1,14 +1,14 @@
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
import {View} from 'angular2/src/core/annotations_impl/view';
import {NavController, HeaderTemplate, Toolbar, Content} from 'ionic/ionic';
import {NavController, Toolbar, Content} from 'ionic/ionic';
import {SecondPage} from './second-page';
@Component({selector: 'ion-view'})
@View({
templateUrl: 'pages/first-page.html',
directives: [HeaderTemplate, Toolbar, Content]
directives: [Toolbar, Content]
})
export class FirstPage {
constructor(

View File

@@ -1,5 +1,5 @@
<ion-toolbar *header><ion-title>Second Page</ion-title></ion-toolbar>
<ion-toolbar><ion-title>Second Page</ion-title></ion-toolbar>
<ion-content class="padding">

View File

@@ -1,14 +1,14 @@
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
import {View} from 'angular2/src/core/annotations_impl/view';
import {NavController, NavParams, HeaderTemplate, Toolbar, Content} from 'ionic/ionic';
import {NavController, NavParams, Toolbar, Content} from 'ionic/ionic';
import {ThirdPage} from './third-page';
@Component()
@Component({selector: 'ion-view'})
@View({
templateUrl: 'pages/second-page.html',
directives: [HeaderTemplate, Toolbar, Content]
directives: [Toolbar, Content]
})
export class SecondPage {
constructor(

View File

@@ -1,5 +1,5 @@
<ion-toolbar *header><ion-title>Third Page</ion-title></ion-toolbar>
<ion-toolbar><ion-title>Third Page</ion-title></ion-toolbar>
<ion-content class="padding">

View File

@@ -1,13 +1,13 @@
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
import {View} from 'angular2/src/core/annotations_impl/view';
import {NavController, HeaderTemplate, Toolbar, Content} from 'ionic/ionic';
import {NavController, Toolbar, Content} from 'ionic/ionic';
@Component()
@Component({selector: 'ion-view'})
@View({
templateUrl: 'pages/third-page.html',
directives: [HeaderTemplate, Toolbar, Content]
directives: [Toolbar, Content]
})
export class ThirdPage {
constructor(

View File

@@ -34,7 +34,6 @@ import {BackButton} from './back-button';
})
export class Toolbar {
constructor(navItem: NavItem, elementRef: ElementRef) {
this.navItem = navItem;
this.domElement = elementRef.domElement;
this.config = Toolbar.config.invoke(this);
@@ -95,18 +94,3 @@ export class Toolbar {
}
new IonicComponent(Toolbar, {});
/*
Used to find and register headers in a view, and this directive's
content will be moved up to the common toolbar location, and created
using the same context as the view's content area.
*/
@Directive({
selector: 'template[header]'
})
export class HeaderTemplate {
constructor(navItem: NavItem, protoViewRef: ProtoViewRef) {
navItem.addHeader(protoViewRef);
}
}

View File

@@ -2,7 +2,8 @@
// Toolbar
// --------------------------------------------------
$toolbar-background: #f7f7f8 !default;
$toolbar-background-color: #fff !default;
$toolbar-order: (
back-button: 10,
title: 20,
@@ -11,22 +12,11 @@ $toolbar-order: (
);
.toolbar-container {
background: $toolbar-background;
}
ion-toolbar {
background: $toolbar-background-color;
flex-direction: row;
align-items: center;
justify-content: space-between;
// by default ion-toolbar is display:none and
// the transition animation will add the show class
display: none;
&.show-toolbar {
display: flex;
}
}
.toolbar-inner {