From c0223edabe629ba204536d9394de1155cb8d646b Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Fri, 31 Jul 2015 22:35:32 -0500 Subject: [PATCH] render views working --- ionic/components/app/app.ts | 28 ++++++--- ionic/components/item/item.ts | 10 +-- ionic/components/nav-bar/nav-bar.ts | 17 ++++-- ionic/components/nav/nav.ts | 4 +- ionic/components/nav/pane.ts | 17 ++---- .../nav/test/basic/pages/first-page.ts | 5 +- ionic/components/tabs/tab.ts | 2 +- ionic/components/toolbar/toolbar.ts | 6 +- ionic/components/view/view-controller.ts | 5 ++ ionic/components/view/view-item.ts | 61 ++++++++++--------- ionic/transitions/transition.ts | 7 ++- 11 files changed, 94 insertions(+), 68 deletions(-) diff --git a/ionic/components/app/app.ts b/ionic/components/app/app.ts index f58c91a540..51ae919c66 100644 --- a/ionic/components/app/app.ts +++ b/ionic/components/app/app.ts @@ -1,4 +1,4 @@ -import {bootstrap, Compiler, ElementRef, NgZone, bind, ViewRef, DynamicComponentLoader} from 'angular2/angular2'; +import {Component, View, bootstrap, Compiler, ElementRef, NgZone, bind, ViewRef, DynamicComponentLoader, Injector} from 'angular2/angular2'; import {AppViewManager} from 'angular2/src/core/compiler/view_manager'; import {NgZone} from 'angular2/src/core/zone/ng_zone'; @@ -28,7 +28,7 @@ export class IonicApp { load(appRef) { this.ref(appRef); - this._zone = this.injector().get(NgZone); + this._zone = this.injector.get(NgZone); } focusHolder(val) { @@ -49,7 +49,7 @@ export class IonicApp { return this._ref; } - injector() { + get injector { return this._ref.injector; } @@ -92,10 +92,10 @@ export class IonicApp { * @return Promise that resolves with the ContainerRef created */ appendComponent(component: Type, context=null) { - let loader = this.injector().get(DynamicComponentLoader); + let loader = this.injector.get(DynamicComponentLoader); let rootComponentRef = this.ref()._hostComponent; - return loader.loadNextToLocation(component, rootComponentRef.location) + return loader.loadNextToLocation(component, rootComponentRef.location, this.bindings) .catch(err => { console.error('appendComponent:', err); }); @@ -149,6 +149,18 @@ function initApp(window, document, config) { return app; } +@Component({ + selector: 'test-comp' +}) +@View({ + template: 'test-comp text' +}) +class TestComp { + constructor(config: IonicConfig) { + console.log('TestComp constructor') + } +} + export function ionicBootstrap(component, config, router) { return new Promise(resolve => { try { @@ -186,16 +198,16 @@ export function ionicBootstrap(component, config, router) { let popup = new Popup(app, config); // add injectables that will be available to all child components - let injectableBindings = [ + app.bindings = Injector.resolve([ bind(IonicApp).toValue(app), bind(IonicConfig).toValue(config), bind(IonicRouter).toValue(router), bind(ActionMenu).toValue(actionMenu), bind(Modal).toValue(modal), bind(Popup).toValue(popup) - ]; + ]); - bootstrap(component, injectableBindings).then(appRef => { + bootstrap(component, app.bindings).then(appRef => { app.load(appRef); // append the focus holder if its needed diff --git a/ionic/components/item/item.ts b/ionic/components/item/item.ts index dd13ff121c..d10e95d48c 100644 --- a/ionic/components/item/item.ts +++ b/ionic/components/item/item.ts @@ -14,22 +14,22 @@ import {dom} from 'ionic/util'; @View({ template: `
- +
` /* diff --git a/ionic/components/nav-bar/nav-bar.ts b/ionic/components/nav-bar/nav-bar.ts index 634a92e041..580eca83f9 100644 --- a/ionic/components/nav-bar/nav-bar.ts +++ b/ionic/components/nav-bar/nav-bar.ts @@ -1,6 +1,8 @@ import {Directive, View, Ancestor, Optional, ElementRef, forwardRef} from 'angular2/angular2'; import {ProtoViewRef} from 'angular2/src/core/compiler/view_ref'; +import {TemplateRef} from 'angular2/angular2'; + import {ToolbarBase} from '../toolbar/toolbar'; import {IonicConfig} from '../../config/config'; import {IonicComponent, IonicView} from '../../config/annotations'; @@ -26,14 +28,14 @@ import {ViewItem} from '../view/view-item';
- +
- +
- +
`, @@ -77,7 +79,7 @@ export class Navbar extends ToolbarBase { didEnter() { const titleEle = this._ttEle || (this._ttEle = this.getNativeElement().querySelector('ion-title')); - this.app.title(titleEle.textContent); + titleEle && this.app.title(titleEle.textContent); } } @@ -137,7 +139,10 @@ class NavbarItem { selector: 'template[navbar]' }) export class NavbarTemplate { - constructor(@Optional() item: ViewItem, protoViewRef: ProtoViewRef) { - item && item.addProtoViewRef('navbar', protoViewRef); + constructor( + @Optional() item: ViewItem, + @Optional() templateRef: TemplateRef + ) { + item && item.addTemplateRef('navbar', templateRef); } } diff --git a/ionic/components/nav/nav.ts b/ionic/components/nav/nav.ts index b4fc8a544c..7de1de0676 100644 --- a/ionic/components/nav/nav.ts +++ b/ionic/components/nav/nav.ts @@ -27,7 +27,9 @@ export class Nav extends ViewController { super(ancestorViewCtrl, injector, elementRef); } - onIonInit() { + onInit() { + super.onInit(); + if (this.root) { this.push(this.root); } diff --git a/ionic/components/nav/pane.ts b/ionic/components/nav/pane.ts index 83653c6a2e..dea4cdf88b 100644 --- a/ionic/components/nav/pane.ts +++ b/ionic/components/nav/pane.ts @@ -1,5 +1,4 @@ -import {Component, Directive, View, ElementRef, Parent, Inject, forwardRef} from 'angular2/angular2'; -import {bind} from 'angular2/di'; +import {Component, Directive, View, ElementRef, Inject, forwardRef, Injector, bind} from 'angular2/angular2'; import {Ion} from '../ion'; import {IonicConfig} from '../../config/config'; @@ -13,6 +12,10 @@ export class PaneController { constructor(viewCtrl: ViewController) { this.panes = {}; this.viewCtrl = viewCtrl; + + this.bindings = Injector.resolve([ + bind(ViewController).toValue(viewCtrl) + ]); } get(itemStructure, callback) { @@ -32,16 +35,8 @@ export class PaneController { // create a new nav pane this.panes[key] = null; - 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 - // viewCtrl.compiler.compileInHost(this.ComponentType).then(componentProtoViewRef => { - - // }); - viewCtrl.loader.loadNextToLocation(Pane, viewCtrl.anchorElementRef(), injector).then(() => { + viewCtrl.loader.loadNextToLocation(Pane, viewCtrl.anchorElementRef(), this.bindings).then(() => { // get the pane reference by name pane = this.panes[key]; diff --git a/ionic/components/nav/test/basic/pages/first-page.ts b/ionic/components/nav/test/basic/pages/first-page.ts index 235cad22a9..ec057024fb 100644 --- a/ionic/components/nav/test/basic/pages/first-page.ts +++ b/ionic/components/nav/test/basic/pages/first-page.ts @@ -8,13 +8,13 @@ import {ThirdPage} from './third-page'; @IonicView({ template: '' + '' + - 'First Page' + + '{{title}}' + '' + '' + '' + '' + '' + - '

First Page

' + + '

{{title}}

' + '

' + '

' + '

' + @@ -30,6 +30,7 @@ export class FirstPage { config: IonicConfig ) { this.nav = nav; + this.title = 'First Page'; this.pushPage = SecondPage; this.pushData = { diff --git a/ionic/components/tabs/tab.ts b/ionic/components/tabs/tab.ts index 35a8ef4dcc..da8a6d0220 100644 --- a/ionic/components/tabs/tab.ts +++ b/ionic/components/tabs/tab.ts @@ -41,7 +41,7 @@ export class Tab extends ViewController { let item = this.item = new ViewItem(tabs.Ancestor); item.setInstance(this); - item.viewElement(elementRef.nativeElement); + item.viewElementRef(elementRef); tabs.addTab(this); this.navbarView = item.navbarView = () => { diff --git a/ionic/components/toolbar/toolbar.ts b/ionic/components/toolbar/toolbar.ts index e2195b0831..68572cf0f7 100644 --- a/ionic/components/toolbar/toolbar.ts +++ b/ionic/components/toolbar/toolbar.ts @@ -79,14 +79,14 @@ export class ToolbarBase extends Ion {
- +
- +
- +
`, diff --git a/ionic/components/view/view-controller.ts b/ionic/components/view/view-controller.ts index 3a0620573f..1be76e5287 100644 --- a/ionic/components/view/view-controller.ts +++ b/ionic/components/view/view-controller.ts @@ -50,6 +50,11 @@ export class ViewController extends Ion { bind(ViewController).toValue(this), bind(NavController).toValue(new NavController(this)) ]); + + this.bindings = Injector.resolve([ + bind(ViewController).toValue(this), + bind(NavController).toValue(new NavController(this)) + ]); } push(component, params = {}, opts = {}) { diff --git a/ionic/components/view/view-item.ts b/ionic/components/view/view-item.ts index 6a62933e71..4e72813948 100644 --- a/ionic/components/view/view-item.ts +++ b/ionic/components/view/view-item.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, ElementRef, bind} from 'angular2/angular2'; +import {Component, EventEmitter, ElementRef, bind, Injector, ComponentRef} from 'angular2/angular2'; import {DirectiveBinding} from 'angular2/src/core/compiler/element_injector'; import {NavParams} from '../nav/nav-controller'; @@ -17,12 +17,18 @@ export class ViewItem { this.protos = {}; this._nbItms = []; this._promises = []; + + this.templateRefs = {}; } addProtoViewRef(name, protoViewRef) { this.protos[name] = protoViewRef; } + addTemplateRef(name, templateRef) { + this.templateRefs[name] = templateRef; + } + stage(callback) { let viewCtrl = this.viewCtrl; @@ -37,58 +43,57 @@ export class ViewItem { 'class': 'nav-item' } }); - let ionViewComponent = DirectiveBinding.createFromType(this.component, annotation); + let viewComponent = DirectiveBinding.createFromType(this.component, annotation); // compile the Component - viewCtrl.compiler.compileInHost(ionViewComponent).then(componentProtoViewRef => { + viewCtrl.compiler.compileInHost(viewComponent).then(hostProtoViewRef => { // 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 = this.sturcture = this.inspectStructure(componentProtoViewRef); + let itemStructure = this.sturcture = this.inspectStructure(hostProtoViewRef); // get the appropriate Pane which this ViewItem will fit into viewCtrl.panes.get(itemStructure, pane => { this.pane = pane; - // create a new injector just for this ViewItem - let injector = viewCtrl.injector.resolveAndCreateChild([ + let bindings = viewCtrl.bindings.concat(Injector.resolve([ bind(NavParams).toValue(this.params), bind(ViewItem).toValue(this) - ]); + ])); // add the content of the view to the content area // it will already have the correct context let contentContainer = pane.contentContainerRef; - let hostViewRef = contentContainer.create(componentProtoViewRef, -1, null, injector); - // get the component's instance, and set it to the this ViewItem - this.setInstance( viewCtrl.viewMngr.getComponent(new ElementRef(hostViewRef, 0)) ); - this.viewElement( hostViewRef._view.render._view.rootNodes[0] ); + // the same guts as DynamicComponentLoader.loadNextToLocation + var hostViewRef = + contentContainer.createHostView(hostProtoViewRef, -1, bindings); + var newLocation = viewCtrl.viewMngr.getHostElement(hostViewRef); + var component = viewCtrl.viewMngr.getComponent(newLocation); - // remember how to dispose of this reference - this.disposals.push(() => { - contentContainer.remove( contentContainer.indexOf(hostViewRef) ); - }); - - // get the view's context so when creating the navbar - // it uses the same context as the content - let context = { - boundElementIndex: 0, - parentView: { - _view: hostViewRef._view.componentChildViews[0] + var dispose = () => { + var index = contentContainer.indexOf(hostViewRef); + if (index !== -1) { + contentContainer.remove(index); } }; + this.disposals.push(dispose); + var viewComponetRef = new ComponentRef(newLocation, component, dispose); - // get the item container's nav bar + // get the component's instance, and set it to the this ViewItem + this.setInstance(viewComponetRef.instance); + this.viewElementRef(viewComponetRef.location); + + // // get the item container's nav bar let navbarViewContainer = viewCtrl.navbarViewContainer(); - // get the item's navbar protoview - let navbarProtoView = this.protos.navbar; + // // get the item's navbar protoview + let navbarTemplateRef = this.templateRefs.navbar; // add a navbar view if the pane has a navbar container, and the // item's instance has a navbar protoview to go to inside of it - if (navbarViewContainer && navbarProtoView) { - let navbarView = navbarViewContainer.create(navbarProtoView, -1, context, injector); + if (navbarViewContainer && navbarTemplateRef) { + let navbarView = navbarViewContainer.createEmbeddedView(navbarTemplateRef, -1); this.disposals.push(() => { navbarViewContainer.remove( navbarViewContainer.indexOf(navbarView) ); @@ -189,7 +194,7 @@ export class ViewItem { } } - viewElement(val) { + viewElementRef(val) { if (arguments.length) { this._vwEle = val; } diff --git a/ionic/transitions/transition.ts b/ionic/transitions/transition.ts index 0397a88201..68c773b07e 100644 --- a/ionic/transitions/transition.ts +++ b/ionic/transitions/transition.ts @@ -18,7 +18,7 @@ export class Transition extends Animation { let leavingItem = this.leaving = nav.getStagedLeavingItem(); // create animation for the entering item's "ion-view" element - this.enteringView = new Animation(enteringItem.viewElement()); + this.enteringView = new Animation(enteringItem.viewElementRef()); this.enteringView.before.addClass(SHOW_VIEW_CSS); this.enteringView.onPlay(() => { @@ -53,7 +53,7 @@ export class Transition extends Animation { if (leavingItem) { // setup the leaving item if one exists (initial viewing wouldn't have a leaving item) - this.leavingView = new Animation(leavingItem.viewElement()); + this.leavingView = new Animation(leavingItem.viewElementRef()); this.leavingView.after.removeClass(SHOW_VIEW_CSS); let leavingNavbar = this.leavingNavbar = new Animation(leavingItem.navbarElement()); @@ -78,7 +78,8 @@ export class Transition extends Animation { } viewWidth() { - return this._w || (this._w = this.leaving && this.leaving.viewElement().offsetWidth); + // TODO: MAKE MORE BETTER + return this._w || (this._w = this.leaving && this.leaving.viewElementRef().nativeElement.offsetWidth); } /*