refactor(NavController): use ng2 loadNextToLocation

This commit is contained in:
Adam Bradley
2015-10-09 16:16:38 -05:00
parent 923a492d20
commit 085ee958c4
3 changed files with 94 additions and 127 deletions

View File

@ -527,41 +527,13 @@ export class NavController extends Ion {
* @private * @private
* TODO * TODO
*/ */
createViewComponentRef(type, hostProtoViewRef, viewContainer, viewCtrlBindings) { loadNextToAnchor(type, location, viewCtrl) {
let bindings = this.bindings.concat(viewCtrlBindings); let bindings = this.bindings.concat(Injector.resolve([
// the same guts as DynamicComponentLoader.loadNextToLocation
var hostViewRef =
viewContainer.createHostView(hostProtoViewRef, viewContainer.length, bindings);
var newLocation = this._viewManager.getHostElement(hostViewRef);
var component = this._viewManager.getComponent(newLocation);
var dispose = () => {
var index = viewContainer.indexOf(hostViewRef);
if (index !== -1) {
viewContainer.remove(index);
}
};
// TODO: make-shift ComponentRef_, this is pretty much going to
// break in future versions of ng2, keep an eye on it
return {
location: newLocation,
instance: component,
dispose: dispose
};
}
/**
* @private
* TODO
*/
getBindings(viewCtrl) {
// create bindings to this ViewController and its NavParams
return this.bindings.concat(Injector.resolve([
bind(ViewController).toValue(viewCtrl), bind(ViewController).toValue(viewCtrl),
bind(NavParams).toValue(viewCtrl.params), bind(NavParams).toValue(viewCtrl.params),
])); ]));
return this._loader.loadNextToLocation(type, location, bindings);
} }
/** /**

View File

@ -192,65 +192,70 @@ export class Nav extends NavController {
if (structure.tabs) { if (structure.tabs) {
// the component being loaded is an <ion-tabs> // the component being loaded is an <ion-tabs>
// Tabs is essentially a pane, cuz it has its own navbar and content containers // Tabs is essentially a pane, cuz it has its own navbar and content containers
let contentContainerRef = this._viewManager.getViewContainer(this.anchorElementRef()); this.loadNextToAnchor(componentType, this.anchorElementRef(), viewCtrl).then(componentRef => {
let viewComponentRef = this.createViewComponentRef(componentType, hostProtoViewRef, contentContainerRef, this.getBindings(viewCtrl));
viewComponentRef.instance._paneView = true;
viewCtrl.disposals.push(() => { componentRef.instance._paneView = true;
viewComponentRef.dispose();
}); viewCtrl.disposals.push(() => {
componentRef.dispose();
});
viewCtrl.onReady().then(() => {
done();
});
viewCtrl.onReady().then(() => {
done();
}); });
} else { } else {
// normal ion-view going into pane // normal ion-view going into pane
this.getPane(structure, viewCtrl, (pane) => { this.getPane(structure, viewCtrl, (pane) => {
// add the content of the view into the pane's content area // add the content of the view into the pane's content area
let viewComponentRef = this.createViewComponentRef(componentType, hostProtoViewRef, pane.contentContainerRef, this.getBindings(viewCtrl)); this.loadNextToAnchor(componentType, pane.contentAnchorRef, viewCtrl).then(componentRef => {
viewCtrl.disposals.push(() => {
viewComponentRef.dispose();
// remove the pane if there are no view items left
pane.totalViews--;
if (pane.totalViews === 0) {
pane.dispose && pane.dispose();
}
});
// count how many ViewControllers are in this pane
pane.totalViews++;
// a new ComponentRef has been created
// set the ComponentRef's instance to this ViewController
viewCtrl.setInstance(viewComponentRef.instance);
// remember the ElementRef to the content that was just created
viewCtrl.viewElementRef(viewComponentRef.location);
// get the NavController's container for navbars, which is
// the place this NavController will add each ViewController's navbar
let navbarContainerRef = pane.navbarContainerRef;
// get this ViewController's navbar TemplateRef, which may not
// exist if the ViewController's template didn't have an <ion-navbar *navbar>
let navbarTemplateRef = viewCtrl.getNavbarTemplateRef();
// create the navbar view if the pane has a navbar container, and the
// ViewController's instance has a navbar TemplateRef to go to inside of it
if (navbarContainerRef && navbarTemplateRef) {
let navbarView = navbarContainerRef.createEmbeddedView(navbarTemplateRef, -1);
viewCtrl.disposals.push(() => { viewCtrl.disposals.push(() => {
let index = navbarContainerRef.indexOf(navbarView); componentRef.dispose();
if (index > -1) {
navbarContainerRef.remove(index); // remove the pane if there are no view items left
pane.totalViews--;
if (pane.totalViews === 0) {
pane.dispose && pane.dispose();
} }
}); });
}
done(); // count how many ViewControllers are in this pane
pane.totalViews++;
// a new ComponentRef has been created
// set the ComponentRef's instance to this ViewController
viewCtrl.setInstance(componentRef.instance);
// remember the ElementRef to the content that was just created
viewCtrl.viewElementRef(componentRef.location);
// get the NavController's container for navbars, which is
// the place this NavController will add each ViewController's navbar
let navbarContainerRef = pane.navbarContainerRef;
// get this ViewController's navbar TemplateRef, which may not
// exist if the ViewController's template didn't have an <ion-navbar *navbar>
let navbarTemplateRef = viewCtrl.getNavbarTemplateRef();
// create the navbar view if the pane has a navbar container, and the
// ViewController's instance has a navbar TemplateRef to go to inside of it
if (navbarContainerRef && navbarTemplateRef) {
let navbarView = navbarContainerRef.createEmbeddedView(navbarTemplateRef, -1);
viewCtrl.disposals.push(() => {
let index = navbarContainerRef.indexOf(navbarView);
if (index > -1) {
navbarContainerRef.remove(index);
}
});
}
done();
});
}); });
} }
} }
@ -273,7 +278,7 @@ export class Nav extends NavController {
} else { } else {
// create a new nav pane // create a new nav pane
this._loader.loadNextToLocation(Pane, this.anchorElementRef(), this.getBindings(viewCtrl)).then(componentRef => { this._loader.loadNextToLocation(Pane, this.anchorElementRef(), this.bindings).then(componentRef => {
// get the pane reference // get the pane reference
pane = this.newPane; pane = this.newPane;
@ -352,17 +357,6 @@ export class Nav extends NavController {
} }
/**
* @private
* TODO
* @param {TODO} elementBinder TODO
* @param {TODO} id TODO
* @return {TODO} TODO
*/
function isComponent(elementBinder, id) {
return (elementBinder && elementBinder.componentDirective && elementBinder.componentDirective.metadata.id == id);
}
/** /**
* @private * @private
*/ */
@ -393,9 +387,9 @@ class NavBarAnchor {
class ContentAnchor { class ContentAnchor {
constructor( constructor(
@Host() @Inject(forwardRef(() => Pane)) pane: Pane, @Host() @Inject(forwardRef(() => Pane)) pane: Pane,
viewContainerRef: ViewContainerRef elementRef: ElementRef
) { ) {
pane.contentContainerRef = viewContainerRef; pane.contentAnchorRef = elementRef;
} }
} }

View File

@ -153,40 +153,44 @@ export class Tab extends NavController {
loadContainer(componentType, hostProtoViewRef, viewCtrl, done) { loadContainer(componentType, hostProtoViewRef, viewCtrl, done) {
let viewComponentRef = this.createViewComponentRef(componentType, hostProtoViewRef, this.contentContainerRef, this.getBindings(viewCtrl)); this.loadNextToAnchor(componentType, this.contentAnchorRef, viewCtrl).then(componentRef => {
viewCtrl.disposals.push(() => {
viewComponentRef.dispose();
});
// a new ComponentRef has been created
// set the ComponentRef's instance to this ViewController
viewCtrl.setInstance(viewComponentRef.instance);
// remember the ElementRef to the content that was just created
viewCtrl.viewElementRef(viewComponentRef.location);
// get the NavController's container for navbars, which is
// the place this NavController will add each ViewController's navbar
let navbarContainerRef = this.tabs.navbarContainerRef;
// get this ViewController's navbar TemplateRef, which may not
// exist if the ViewController's template didn't have an <ion-navbar *navbar>
let navbarTemplateRef = viewCtrl.getNavbarTemplateRef();
// create the navbar view if the pane has a navbar container, and the
// ViewController's instance has a navbar TemplateRef to go to inside of it
if (navbarContainerRef && navbarTemplateRef) {
let navbarView = navbarContainerRef.createEmbeddedView(navbarTemplateRef, -1);
viewCtrl.disposals.push(() => { viewCtrl.disposals.push(() => {
let index = navbarContainerRef.indexOf(navbarView); componentRef.dispose();
if (index > -1) {
navbarContainerRef.remove(index);
}
}); });
}
done(); // a new ComponentRef has been created
// set the ComponentRef's instance to this ViewController
viewCtrl.setInstance(componentRef.instance);
// remember the ElementRef to the content that was just created
viewCtrl.viewElementRef(componentRef.location);
// get the NavController's container for navbars, which is
// the place this NavController will add each ViewController's navbar
let navbarContainerRef = this.tabs.navbarContainerRef;
// get this ViewController's navbar TemplateRef, which may not
// exist if the ViewController's template didn't have an <ion-navbar *navbar>
let navbarTemplateRef = viewCtrl.getNavbarTemplateRef();
// create the navbar view if the pane has a navbar container, and the
// ViewController's instance has a navbar TemplateRef to go to inside of it
if (navbarContainerRef && navbarTemplateRef) {
let navbarView = navbarContainerRef.createEmbeddedView(navbarTemplateRef, -1);
viewCtrl.disposals.push(() => {
let index = navbarContainerRef.indexOf(navbarView);
if (index > -1) {
navbarContainerRef.remove(index);
}
});
}
done();
});
} }
} }
@ -194,10 +198,7 @@ export class Tab extends NavController {
@Directive({selector: 'template[content-anchor]'}) @Directive({selector: 'template[content-anchor]'})
class TabContentAnchor { class TabContentAnchor {
constructor( constructor(@Host() tab: Tab, elementRef: ElementRef) {
@Host() tab: Tab, tab.contentAnchorRef = elementRef;
viewContainerRef: ViewContainerRef
) {
tab.contentContainerRef = viewContainerRef;
} }
} }