I have been working a JavaScript MVC routing engine, which I hope to release soon, so here is a little overview of what is out there:
route.js, usage:
route('#/Learn').bind(function(){
$('.panel').hide();
$('#Learn').show();
});
sammy, usage:
$.sammy(function() {
this.get('#/', function() {
$('#main').text('Welcome!');
});
});
angularjs, usage:
function TicTacToeCntl(){
this.cellStyle= {
'height': '20px',
'width': '20px',
'border': '1px solid black',
'text-align': 'center',
'vertical-align': 'middle',
'cursor': 'pointer'
};
this.reset();
this.$watch('$location.hashPath', this.readUrl);
}
TicTacToeCntl.prototype = {
dropPiece: function(row, col) {
if (!this.winner && !this.board[row][col]) {
this.board[row][col] = this.nextMove;
this.nextMove = this.nextMove == 'X' ? 'O' : 'X';
this.setUrl();
}
},
reset: function(){
this.board = [
['', '', ''],
['', '', ''],
['', '', '']
];
this.nextMove = 'X';
this.winner = '';
this.setUrl();
},
grade: function(){
var b = this.board;
this.winner =
row(0) || row(1) || row(2) ||
col(0) || col(1) || col(2) ||
diagonal(-1) || diagonal(1);
function row(r) { return same(b[r][0], b[r][1], b[r][2]);}
function col(c) { return same(b[0][c], b[1][c], b[2][c]);}
function diagonal(i) { return same(b[0][1-i], b[1][1], b[2][1+i]);}
function same(a, b, c) { return (a==b && b==c) ? a : '';};
},
setUrl: function(){
var rows = [];
angular.foreach(this.board, function(row){
rows.push(row.join(','));
});
this.$location.hashPath = rows.join(';') + '/' + this.nextMove;
},
readUrl: function(value) {
if (value) {
value = value.split('/');
this.nextMove = value[1];
angular.foreach(value[0].split(';'), function(row, i){
this.board[i] = row.split(',');
}, this);
this.grade();
} else {
this.reset();
}
}
};
While these are all nice, I wanted to do something little different. I would like to have true MVC style of JavaScript app, which would mimic the ASP.NET MVC project file structure with a folder for views, models, controllers and helpers. I would like to be able to do arbitrary binding of hash paths, to different controllers, in a similar manner the .NET MVC app does it, for example:
(function(routes) {
routes.mapRoute(
"Test", // Name.
"foo/bar/{controller}/{action}/{p1}/{p3}/{p2}", // Path.
{ controller: "Page", action: "Index", p1: "default1", p2: "default2", p3: "default3" } // Defaults.
);
routes.mapRoute(
"Default", // Name.
"{controller}/{action}/{id}", // Path.
{controller: "Page", action: "Index", id: ""} // Defaults.
);
})(MyApp.routes);