add back button platform config

This commit is contained in:
Andrew
2015-03-31 10:44:31 -06:00
parent 1adb91e6d8
commit 54d3418d50
9 changed files with 190 additions and 118 deletions

View File

@ -1,10 +1,18 @@
import {Component, Template, Inject, Parent, NgElement} from 'angular2/angular2' import {Component, Template, NgElement} from 'angular2/angular2'
import {ComponentConfig} from 'ionic2/config/component-config' import {ComponentConfig} from 'ionic2/config/component-config'
import {Log} from 'ionic2/util' import {Log} from 'ionic2/util'
import {Compiler} from 'angular2/src/core/compiler/compiler'
import {EventManager} from 'angular2/src/core/events/event_manager'
import {PrivateComponentLocation} from 'angular2/src/core/compiler/private_component_location'
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader'
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader'
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy'
@Component({ @Component({
selector: 'ion-nav', selector: 'ion-nav',
bind: { bind: {
initial: 'initial'
}, },
services: [] services: []
}) })
@ -12,10 +20,34 @@ import {Log} from 'ionic2/util'
inline: `<content></content>` inline: `<content></content>`
}) })
export class NavView { export class NavView {
constructor(@NgElement() element: NgElement) { constructor(
console.log('Nav View constructed') @NgElement() element: NgElement,
eventManager: EventManager,
compiler: Compiler,
location: PrivateComponentLocation,
loader: PrivateComponentLoader,
directiveMetadataReader: DirectiveMetadataReader,
shadowDomStrategy: ShadowDomStrategy
) {
this.attacher = new Attacher({
compiler,
element,
location,
loader,
directiveMetadataReader,
eventManager,
shadowDomStrategy
})
this._views = [] this._children = []
console.log('Nav View constructed')
}
set initial(Type) {
if (!this.initialized) {
this.initialized = true
this.push(Type)
}
} }
/** /**
@ -24,14 +56,16 @@ export class NavView {
* @param view the new view * @param view the new view
* @param shouldAnimate whether to animate * @param shouldAnimate whether to animate
*/ */
push(view, shouldAnimate) { push(Type, shouldAnimate) {
this._views.push(view) //TODO animation
if(shouldAnimate) { let current = this._children[this._children.length - 1]
this._animateIn(view) current && current.hide()
}
Log.log('NAV: PUSH', view, 'Animate?', shouldAnimate) this.attacher.attachComponent(Type).then(child => {
this._children.push(child)
})
Log.log('NAV: PUSH', Type.name, 'Animate?', shouldAnimate)
} }
/** /**
@ -40,12 +74,15 @@ export class NavView {
* @param shouldAnimate whether to animate * @param shouldAnimate whether to animate
*/ */
pop(shouldAnimate) { pop(shouldAnimate) {
last = this._views.pop() // TODO animation
let current = this._children.pop()
if(shouldAnimate) { if (current) {
this._animateOut(last) current.remove()
}
let last = this._children[this._children.length - 1]
if (last) {
last.show()
} }
return last return last
} }
@ -69,3 +106,66 @@ export class NavView {
} }
} }
class Attacher {
constructor({
location,
element,
directiveMetadataReader,
compiler,
shadowDomStrategy,
eventManager
}) {
this.location = location
this.element = element
this.directiveMetadataReader = directiveMetadataReader
this.compiler = compiler
this.shadowDomStrategy = shadowDomStrategy
this.eventManager = eventManager
}
attachComponent(Type) {
let parentInjector = this.location._elementInjector
let childInjector = parentInjector._proto.instantiate(
/* parent */ parentInjector,
/* host */ null
)
let childContainer = document.createElement('div')
childContainer.classList.add('test-child-container')
this.element.domElement.appendChild(childContainer)
let childNgElement = new NgElement(childContainer)
childInjector._preBuiltObjects = parentInjector._preBuiltObjects
childInjector._preBuiltObjects.element = childNgElement
let annotation = this.directiveMetadataReader.read(Type).annotation
return this.compiler.compile(Type).then((protoView) => {
let context = childInjector.createPrivateComponent(Type, annotation);
let view = protoView.instantiate(childInjector, this.eventManager)
view.hydrate(parentInjector.getShadowDomAppInjector(), childInjector, null, context, null)
this.shadowDomStrategy.attachTemplate(childNgElement.domElement, view)
this.location._view.componentChildViews.push(view)
this.location._view.changeDetector.addChild(view.changeDetector)
return {
remove() {
// TODO actually remove it from the angular tree
// setTimeout(() => { view.dehydrate() })
childContainer.parentNode.removeChild(childContainer)
},
hide() {
// view.dehydrate()
childContainer.style.display = 'none'
},
show() {
childContainer.style.display = ''
// view.hydrate()
},
}
})
}
}

View File

@ -1,4 +1,2 @@
<ion-nav> <ion-nav [initial]="initial">
<my-page>
</my-page>
</ion-nav> </ion-nav>

View File

@ -1,112 +1,17 @@
import {bootstrap} from 'angular2/core' import {bootstrap} from 'angular2/core'
import {Component, Template, NgElement, Parent} from 'angular2/angular2' import {Component, Template} from 'angular2/angular2'
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver'
import {Compiler} from 'angular2/src/core/compiler/compiler'
import {EventManager} from 'angular2/src/core/events/event_manager'
import {NavView} from 'ionic2/components/nav-view/nav-view' import {NavView} from 'ionic2/components/nav-view/nav-view'
import {View} from 'ionic2/components/view/view'
import {Log} from 'ionic2/util' import {Log} from 'ionic2/util'
import {PrivateComponentLocation} from 'angular2/src/core/compiler/private_component_location' import {FirstPage} from 'app/pages/first-page'
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader'
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader'
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy'
@Component({
selector: 'my-page'
})
@Template({
inline: '<div>Hello, inside page {{num}}</div>'
})
export class InsidePage {
constructor(
ele: NgElement,
@Parent() myPage: MyPage
) {
console.log(myPage)
this.num = Math.random()
ele.domElement.style.backgroundColor = `rgba(255,0,0,${this.num})`
}
}
@Component({
selector: 'my-page',
services: [Compiler, PrivateComponentLocation]
})
@Template({
inline: `<div><h2>I'm a page!</h2>
<button class="button" (click)="push()">Push</button>
<button class="button" (click)="pop()">Pop</button>
</div>`
})
export class MyPage {
constructor(
@NgElement() ele:NgElement,
eventManager: EventManager,
compiler: Compiler,
location: PrivateComponentLocation,
loader: PrivateComponentLoader,
reader: DirectiveMetadataReader,
shadowDomStrategy: ShadowDomStrategy
) {
this.ele = ele
this.location = location
this.loader = loader
this.reader = reader
this.compiler = compiler
this.eventManager = eventManager
this.shadowDomStrategy = shadowDomStrategy
this._children = []
}
push() {
let childInjector = this.location._elementInjector._proto.instantiate(
/* parent */ this.location._elementInjector,
/* host */ null
)
let childContainer = document.createElement('div')
childContainer.classList.add('test-child-container')
this.ele.domElement.appendChild(childContainer)
let childNgElement = new NgElement(childContainer)
childInjector._preBuiltObjects = this.location._elementInjector._preBuiltObjects
childInjector._preBuiltObjects.element = childNgElement
let annotation = this.reader.read(InsidePage).annotation
this.compiler.compile(InsidePage).then((protoView) => {
let context = childInjector.createPrivateComponent(InsidePage, annotation);
let view = protoView.instantiate(childInjector, this.eventManager)
view.hydrate(childInjector.getShadowDomAppInjector(), childInjector, null, context, null)
this.shadowDomStrategy.attachTemplate(childNgElement.domElement, view)
this.location._view.componentChildViews.push(view)
this.location._view.changeDetector.addChild(view.changeDetector)
this._children.push({
remove() {
view.dehydrate()
childContainer.parentNode.removeChild(childContainer)
}
})
})
}
pop() {
var last = this._children.pop()
if (!last) return;
last.remove()
}
}
@Component({ selector: '[ion-app]' }) @Component({ selector: '[ion-app]' })
@Template({ @Template({
directives: [NavView, View, MyPage], directives: [NavView],
url: 'main.html' url: 'main.html'
}) })
class IonicApp { class IonicApp {
constructor() { constructor() {
this.initial = FirstPage
console.log('IonicApp Start') console.log('IonicApp Start')
} }
} }

View File

@ -0,0 +1,3 @@
<ion-view view-title="First Page">
<button (click)="nextPage()">Push Page 2</button>
</ion-view>

View File

@ -0,0 +1,23 @@
import {Component, Template, Parent} from 'angular2/angular2'
import {NavView} from 'ionic2/components/nav-view/nav-view'
import {View} from 'ionic2/components/view/view'
import {SecondPage} from 'app/pages/second-page'
@Component({
selector: 'first-page'
})
@Template({
url: 'pages/first-page.html',
directives: [View]
})
export class FirstPage {
constructor(
@Parent() navView: NavView
) {
this.navView = navView
}
nextPage() {
this.navView.push(SecondPage)
}
}

View File

@ -0,0 +1,3 @@
<ion-view view-title="Second Page">
<button (click)="prevPage()">Pop This Page</button>
</ion-view>

View File

@ -0,0 +1,21 @@
import {Component, Template, Parent} from 'angular2/angular2'
import {NavView} from 'ionic2/components/nav-view/nav-view'
import {View} from 'ionic2/components/view/view'
@Component({
selector: 'second-page'
})
@Template({
url: 'pages/second-page.html',
directives: [View]
})
export class SecondPage {
constructor(
@Parent() navView: NavView
) {
this.navView = navView
}
prevPage() {
this.navView.pop()
}
}

View File

@ -3,13 +3,21 @@ import {ComponentConfig} from 'ionic2/config/component-config'
export let BackButtonConfig = new ComponentConfig('back-button') export let BackButtonConfig = new ComponentConfig('back-button')
BackButtonConfig
.platform('ios', instance => {
instance.domElement.querySelector('.back-button-icon').classList.add('ion-ios-arrow-back')
})
.platform('android', instance => {
instance.domElement.querySelector('.back-button-icon').classList.add('ion-android-arrow-back')
})
@Component({ @Component({
selector: '.back-button', selector: '.back-button',
services: [BackButtonConfig] services: [BackButtonConfig]
}) })
@Template({ @Template({
inline: ` inline: `
<icon class="back-button-icon ion-ios-arrow-back"></icon> <icon class="back-button-icon"></icon>
<div class="back-button-text"> <div class="back-button-text">
<div class="back-default">Back</div> <div class="back-default">Back</div>
<div class="back-title"></div> <div class="back-title"></div>

View File

@ -17,6 +17,7 @@ export function ComponentConfig(componentCssName) {
static classes() { static classes() {
Config.classProperties || (Config.classProperties = []) Config.classProperties || (Config.classProperties = [])
Config.classProperties.push.apply(Config.classProperties, arguments) Config.classProperties.push.apply(Config.classProperties, arguments)
return Config
} }
static delegate(delegateName) { static delegate(delegateName) {
let self = { let self = {
@ -27,6 +28,13 @@ export function ComponentConfig(componentCssName) {
} }
return self return self
} }
static platform(name, Class) {
Config.platformFns = Config.platformFns || []
if (name === platformName) {
Config.platformFns.unshift(Class)
}
return Config
}
static addCase(delegateName, condition, DelegateConstructor) { static addCase(delegateName, condition, DelegateConstructor) {
Config.registry || (Config.registry = {}) Config.registry || (Config.registry = {})
var array = (Config.registry[delegateName] || (Config.registry[delegateName] = [])) var array = (Config.registry[delegateName] || (Config.registry[delegateName] = []))
@ -53,6 +61,9 @@ export function ComponentConfig(componentCssName) {
let propertyValue = instance[Config.classProperties[i]] let propertyValue = instance[Config.classProperties[i]]
instance.domElement.classList.add(`${componentCssName}-${propertyValue}`) instance.domElement.classList.add(`${componentCssName}-${propertyValue}`)
} }
for (let i = 0; i < (Config.platformFns || []).length; i++) {
new Config.platformFns[i](instance)
}
return { return {
getDelegate(delegateName) { getDelegate(delegateName) {
let registry = Config.registry && Config.registry[delegateName] || [] let registry = Config.registry && Config.registry[delegateName] || []