Basic NavController working with demo

This commit is contained in:
Max Lynch
2013-09-16 21:56:22 -05:00
parent 19d2aa5432
commit 0f5ce5b76e
5 changed files with 208 additions and 18 deletions

7
hacking/Button.js Normal file
View File

@ -0,0 +1,7 @@
(function(window, document, ionic) {
ionic.Button = function(opts) {
this.el = opts.el;
};
ionic.Button.prototype = {
}
})(this, document, ionic = this.ionic || {});

View File

@ -1,9 +1,43 @@
(function(window, document, ionic) { (function(window, document, ionic) {
NavBar = function() { NavBar = function(opts) {
this.el = opts.el;
this._titleEl = this.el.querySelector('.title');
}; };
NavBar.prototype = { NavBar.prototype = {
shouldGoBack: function() {},
setTitle: function(title) {
if(!this._titleEl) {
return;
}
this._titleEl.innerHTML = title;
},
showBackButton: function(shouldShow) {
var _this = this;
if(!this._currentBackButton) {
var back = document.createElement('a');
back.className = 'button back';
back.innerHTML = 'Back';
this._currentBackButton = back;
this._currentBackButton.onclick = function(event) {
_this.shouldGoBack && _this.shouldGoBack();
}
}
if(shouldShow && !this._currentBackButton.parentNode) {
// Prepend the back button
this.el.insertBefore(this._currentBackButton, this.el.firstChild);
} else if(!shouldShow && this._currentBackButton.parentNode) {
// Remove the back button if it's there
this._currentBackButton.parentNode.removeChild(this._currentBackButton);
}
}
}; };
})(this, document, ion = this.ionic || {}); })(this, document, ion = this.ionic || {});

View File

@ -1,7 +1,16 @@
(function(window, document, ionic) { (function(window, document, ionic) {
NavController = function(opts) { NavController = function(opts) {
var _this = this;
this.navBar = opts.navBar; this.navBar = opts.navBar;
this.content = opts.content;
this.controllers = opts.controllers || []; this.controllers = opts.controllers || [];
// TODO: Is this the best way?
this.navBar.shouldGoBack = function() {
_this.pop();
}
}; };
NavController.prototype = { NavController.prototype = {
@ -12,6 +21,8 @@
return this.topController; return this.topController;
}, },
push: function(controller) { push: function(controller) {
var last = this.topController;
this.controllers.push(controller); this.controllers.push(controller);
// Indicate we are switching controllers // Indicate we are switching controllers
@ -23,27 +34,57 @@
// Actually switch the active controllers // Actually switch the active controllers
// Remove the old one
last && last.detach();
// Grab the top controller on the stack // Grab the top controller on the stack
var next = this.controllers[this.controllers.length - 1]; var next = this.controllers[this.controllers.length - 1];
this.content.el.appendChild(next.el);
// Switch to it (TODO: Animate or such things here) // Switch to it (TODO: Animate or such things here)
this.topController = next; this.topController = next;
this._updateNavBar();
return controller; return controller;
}, },
pop: function() { pop: function() {
var next, last; var next, last;
// Make sure we keep one on the stack at all times
if(this.controllers.length < 2) {
return;
}
// Grab the controller behind the top one on the stack // Grab the controller behind the top one on the stack
last = this.controllers.pop(); last = this.controllers.pop();
// Remove the old one
last && last.detach();
next = this.controllers[this.controllers.length - 1]; next = this.controllers[this.controllers.length - 1];
this.content.el.appendChild(next.el);
// Switch to it (TODO: Animate or such things here) // Switch to it (TODO: Animate or such things here)
this.topController = next; this.topController = next;
this._updateNavBar();
return last; return last;
} },
_updateNavBar: function() {
this.navBar.setTitle(this.topController.title);
if(this.controllers.length > 1) {
this.navBar.showBackButton(true);
} else {
this.navBar.showBackButton(false);
}
},
}; };
})(this, document, this.ionic || {}); })(this, document, this.ionic || {});

View File

@ -1,27 +1,41 @@
describe('NavController', function() { describe('NavController', function() {
var ctrl; var ctrl, navBarEl, contentEl;
var content = function(title) {
return {
el: document.createElement('div'),
title: title,
detach: function() {
this.el.parentNode && this.el.parentNode.removeChild(this.el);
},
attach: function() {
}
}
}
beforeEach(function() { beforeEach(function() {
navBarEl = document.createElement('div');
contentEl = document.createElement('div');
ctrl = new NavController({ ctrl = new NavController({
navBar: new NavBar() navBar: new NavBar({el: navBarEl }),
content: { el: contentEl }
}); });
}); });
it('Should load controllers', function() { it('Should load controllers', function() {
ctrl = new NavController({ ctrl = new NavController({
navBar: new NavBar({el: navBarEl }),
content: { el: contentEl },
controllers: [{}] controllers: [{}]
}); });
expect(ctrl.getControllers().length).toEqual(1); expect(ctrl.getControllers().length).toEqual(1);
}); });
it('Should push controller', function() { it('Should push controller', function() {
ctrl.push({ ctrl.push(content('Page 1'));
title: 'Page 1'
});
expect(ctrl.getControllers().length).toEqual(1); expect(ctrl.getControllers().length).toEqual(1);
ctrl.push({ ctrl.push(content('Page 2'));
title: 'Page 2'
});
expect(ctrl.getControllers().length).toEqual(2); expect(ctrl.getControllers().length).toEqual(2);
var last = ctrl.pop(); var last = ctrl.pop();
expect(ctrl.getControllers().length).toEqual(1); expect(ctrl.getControllers().length).toEqual(1);
@ -30,19 +44,17 @@ describe('NavController', function() {
it('Should change top view controller', function() { it('Should change top view controller', function() {
expect(ctrl.getTopController()).toBe(undefined); expect(ctrl.getTopController()).toBe(undefined);
var c1 = { var c1 = content('Page 1');
title: 'Page 1' var c2 = content('Page 2');
};
var c2 = {
title: 'Page 2'
};
ctrl.push(c1); ctrl.push(c1);
expect(ctrl.getTopController()).toEqual(c1); expect(ctrl.getTopController()).toEqual(c1);
ctrl.push(c2); ctrl.push(c2);
expect(ctrl.getTopController()).toEqual(c2); expect(ctrl.getTopController()).toEqual(c2);
ctrl.pop(); ctrl.pop();
expect(ctrl.getTopController()).toEqual(c1); expect(ctrl.getTopController()).toEqual(c1);
// Make sure we can't pop the first one off
ctrl.pop(); ctrl.pop();
expect(ctrl.getTopController()).toEqual(undefined); expect(ctrl.getTopController()).toEqual(c1);
}); });
}); });

96
hacking/nav.html Normal file
View File

@ -0,0 +1,96 @@
<html>
<head>
<meta charset="utf-8">
<title>Nav Bars</title>
<!-- Sets initial viewport load and disables zooming -->
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<link href="/vendor/font-awesome/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" href="../dist/ionic.css">
</head>
<body>
<section>
<header id="nav-bar" class="bar bar-header bar-dark">
<h1 class="title"></h1>
</header>
<main class="has-header content" id="content">
</main>
</section>
<script src="../../js/ionic-events.js"></script>
<script src="../../js/ionic-gestures.js"></script>
<script src="NavBar.js"></script>
<script src="NavController.js"></script>
<script>
// Grab the sections
var navBar = document.getElementById('nav-bar');
var controller = function(opts) {
this.el = opts.el;
}
controller.prototype = {
detach: function() {
//this.el.style.display = 'none';
var parentNode = this.el.parentNode;
if(!parentNode) {
return;
}
var next = this.el.nextSibling;
this._lastNodeSpot = next;
this._lastNodeParent = parentNode;
parentNode.removeChild(this.el);
},
attach: function() {
//this.el.style.display = 'block';
if(this._lastNodeSpot) {
this._lastNodeParent.insertBefore(this.el, this._lastNodeSpot);
}
}
};
var createPage = function(title) {
var d = document.createElement('div');
d.innerHTML = '<h3>' + title + '</h3><a href=#" class="next button button-success">Next</a>';
var c = new controller({
el: d
});
c.title = title;
return c;
};
var View = function(opts) {
this.el = opts.el;
};
var page1 = createPage('Home');
var page2 = createPage('About');
var page3 = createPage('Cats');
var page4 = createPage('Pizza');
var pages = [page1, page2, page3, page4];
var cd = document.getElementById('content');
var content = new View({
el: cd
});
var c = new NavController({
navBar: new NavBar({ el: navBar }),
content: content
});
c.push(page1);
var currentPage = 1;
document.addEventListener('click', function(event) {
if(event.target.classList.contains('next')) {
c.push(pages[currentPage++ % pages.length]);
}
return false;
});
</script>
</body>
</html>