Archive

JavaScript hash routing

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);

Comments: