Feature/observable ext (#6670)

* refactor(nav-controller): refactor to better support dynamic component loading
This commit is contained in:
Dan Bucholtz
2016-05-27 13:49:37 -05:00
parent 4ba999e6a4
commit dfa991d409
12 changed files with 524 additions and 160 deletions

View File

@@ -68,8 +68,53 @@ class E2EPage {
animation: 'my-fade-in'
});
}
presentNavigableModal(){
let modal = Modal.create(NavigableModal);
this.nav.present(modal);
//this.nav.push(NavigableModal);
}
}
@Page({
template: `
<ion-navbar *navbar>
<ion-title>Page One</ion-title>
</ion-navbar>
<ion-content>
<button full (click)="submit()">Submit</button>
</ion-content>
`
})
class NavigableModal{
constructor(private navController:NavController){
}
submit(){
this.navController.push(NavigableModal2);
}
}
@Page({
template: `
<ion-navbar *navbar>
<ion-title>Page Two</ion-title>
</ion-navbar>
<ion-content>
<button full (click)="submit()">Submit</button>
</ion-content>
`
})
class NavigableModal2{
constructor(private navController:NavController){
}
submit(){
this.navController.pop();
}
}
@Page({
template: `
@@ -105,6 +150,10 @@ class ModalPassData {
this.viewCtrl.dismiss(this.data);
}
onPageLoaded(){
console.log("ModalPassData onPageLoaded fired");
}
onPageWillEnter(){
console.log("ModalPassData onPagewillEnter fired");
}
@@ -280,15 +329,26 @@ class ModalFirstPage {
push() {
let page = ModalSecondPage;
let params = { id: 8675309, myData: [1,2,3,4] };
let opts = { animation: 'ios-transition' };
this.nav.push(page, params, opts);
this.nav.push(page, params);
}
dismiss() {
this.nav.rootNav.pop();
}
onPageLoaded(){
console.log("ModalFirstPage OnPageLoaded fired");
}
onPageWillEnter(){
console.log("ModalFirstPage onPageWillEnter fired");
}
onPageDidEnter(){
console.log("ModalFirstPage onPageDidEnter fired");
}
openActionSheet() {
let actionSheet = ActionSheet.create({
buttons: [
@@ -352,12 +412,21 @@ class ModalFirstPage {
`
})
class ModalSecondPage {
constructor(
private nav: NavController,
params: NavParams
) {
constructor(private nav: NavController, params: NavParams) {
console.log('Second page params:', params);
}
onPageLoaded(){
console.log("ModalSecondPage onPageLoaded");
}
onPageWillEnter(){
console.log("ModalSecondPage onPageWillEnter");
}
onPageDidEnter(){
console.log("ModalSecondPage onPageDidEnter");
}
}
@@ -398,4 +467,4 @@ class FadeOut extends Transition {
.before.addClass('show-page');
}
}
Transition.register('my-fade-out', FadeOut);
Transition.register('my-fade-out', FadeOut);

View File

@@ -1,4 +1,3 @@
<ion-navbar *navbar>
<ion-title>Modals</ion-title>
</ion-navbar>
@@ -7,6 +6,9 @@
<p>
<button (click)="presentModal()">Present modal, pass params</button>
</p>
<p>
<button (click)="presentNavigableModal()">Present modal, push page</button>
</p>
<p>
<button class="e2eOpenModal" (click)="presentModalChildNav()">Present modal w/ child ion-nav</button>
</p>

View File

@@ -0,0 +1,100 @@
import {Modal, ModalCmp, Page, NavController, ViewController} from '../../../../src';
export function run() {
describe('Modal', () => {
describe('create', () => {
it('should have the correct properties on modal view controller instance', () => {
let modalViewController = Modal.create(ComponentToPresent);
expect(modalViewController.modalViewType).toEqual("ComponentToPresent");
expect(modalViewController.componentType).toEqual(ModalCmp);
expect(modalViewController.viewType).toEqual("modal");
expect(modalViewController.isOverlay).toEqual(true);
expect(modalViewController instanceof ViewController).toEqual(true);
});
});
describe('loaded', () => {
it('should call done after loading component and call original ngAfterViewInit method', (done) => {
// arrange
let modal = new Modal({}, {});
let mockInstance = {
ngAfterViewInit: () => {},
loadComponent: () => {}
};
let mockComponentRef = {
instance: "someData"
};
modal.instance = mockInstance;
let ngAfterViewInitSpy = spyOn(mockInstance, "ngAfterViewInit");
spyOn(mockInstance, "loadComponent").and.returnValue(Promise.resolve(mockComponentRef));
let doneCallback = () => {
// assert
expect(ngAfterViewInitSpy).toHaveBeenCalled();
expect(modal.instance).toEqual("someData");
done();
};
// act
modal.loaded(doneCallback);
// (angular calls ngAfterViewInit, we're not testing angular so manually call it)
mockInstance.ngAfterViewInit();
}, 5000);
});
});
describe('ModalCmp', () => {
it('should return a componentRef object after loading component', (done) => {
// arrange
let mockLoader = {
loadNextToLocation: () => {}
};
let mockNavParams = {
data: {
componentType: "myComponentType"
}
};
let mockComponentRef = {};
spyOn(mockLoader, "loadNextToLocation").and.returnValue(Promise.resolve(mockComponentRef));
let modalCmp = new ModalCmp(null, mockLoader, mockNavParams, null);
modalCmp.viewport = "mockViewport";
// act
modalCmp.loadComponent().then(loadedComponentRef => {
// assert
expect(loadedComponentRef).toEqual(mockComponentRef);
expect(mockLoader.loadNextToLocation).toHaveBeenCalledWith(mockNavParams.data.componentType, modalCmp.viewport);
done();
});
}, 5000);
});
}
const STATE_ACTIVE = 'active';
const STATE_INACTIVE = 'inactive';
const STATE_INIT_ENTER = 'init_enter';
const STATE_INIT_LEAVE = 'init_leave';
const STATE_TRANS_ENTER = 'trans_enter';
const STATE_TRANS_LEAVE = 'trans_leave';
const STATE_REMOVE = 'remove';
const STATE_REMOVE_AFTER_TRANS = 'remove_after_trans';
const STATE_FORCE_ACTIVE = 'force_active';
let componentToPresentSpy = {
_ionicProjectContent: () => {},
};
@Page({
template: `<div class="myComponent"></div>`
})
class ComponentToPresent{
constructor(){
}
}