mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-22 13:32:54 +08:00
add back button platform config
This commit is contained in:
@ -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()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,4 +1,2 @@
|
|||||||
<ion-nav>
|
<ion-nav [initial]="initial">
|
||||||
<my-page>
|
|
||||||
</my-page>
|
|
||||||
</ion-nav>
|
</ion-nav>
|
||||||
|
@ -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')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
src/components/nav-view/test/basic/pages/first-page.html
Normal file
3
src/components/nav-view/test/basic/pages/first-page.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<ion-view view-title="First Page">
|
||||||
|
<button (click)="nextPage()">Push Page 2</button>
|
||||||
|
</ion-view>
|
23
src/components/nav-view/test/basic/pages/first-page.js
Normal file
23
src/components/nav-view/test/basic/pages/first-page.js
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
<ion-view view-title="Second Page">
|
||||||
|
<button (click)="prevPage()">Pop This Page</button>
|
||||||
|
</ion-view>
|
21
src/components/nav-view/test/basic/pages/second-page.js
Normal file
21
src/components/nav-view/test/basic/pages/second-page.js
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
||||||
|
@ -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] || []
|
||||||
|
Reference in New Issue
Block a user