What is URL Routing?

URL Routing means that you when click on a link, instead of being routed to another page, you stay on the same page and the content changes. When this happens, usually a “hash” will be appended to your current URL so that the user can go directly to the content they need as well as using back and foward buttons in the browser. URL routing is a foundation of almost any single page web application. Sammy.js is a very simple library for doing just that, and I will provide a simple example of how to use it at the end of this article.

Advantage

-Its fast. The user doesn’t have to wait for the page to load, and it feels like a native app.

Disadvantage

-Search engines have trouble indexing your content. But if that is something you are interested in, there are ways around it.

Example of URL Routing with Sammy.js and Knockout.js

I find that the easiest way to do URL Routing is with sammy.js and knockout js. Lets start with setting up our knockout view model and then initiating sammy.js:

function viewModel() {
    var self = this;
    self.currentView = ko.observable();
    self.views = ko.observableArray(["Home", "About", "Contact"]);
}

var vm = new viewModel();

ko.applyBindings(vm);


Sammy(function () {
    /*
    **"#:view" means that sammy takes whatever is after the hash tag 
    **and applies it to the value of "this.params.view"
    */
    this.get('#:view', function () {
        //Set currentView on your view model
        vm.currentView(this.params.view);
    });
}).run('#Home');//Specify the starting page of your application or leave it blank

In the following HTML snippet, I have a knockout template binding with the name set to the observable “currentView”. And for each of my views I have a separate template with the id of the template matching the name of the view. I am using twitter bootstrap for the navbar, and I apply the css class “active” when the value of “currentView” equals the view reference by each button.

<ul class="nav nav-pills" data-bind="foreach:views">
    <li data-bind="css: {active: $root.currentView() == $data}"> 
        <a  data-bind="text:$data, attr:{href:'#' + $data}"></a>
    </li>
</ul>

<div class="container">
    <div class="row">
        <div class="span12">
            <div data-bind="template: {name: currentView()}"></div>
        </div>
    </div>
</div>

<script type="text/html" id="Home">
    <div>
    <h2>Home</h2>
    </div>
</script>
<script type="text/html" id="About">
    <div>
    <h2>About</h2>    
    </div>
</script>
<script type="text/html" id="Contact">
     <div>
    <h2>Contact</h2>
    </div>
</script>

Here is the the example in jsFiddle:

  • mg1075

    Here is a modification of your example that uses the knockoutjs visible binding instead of a template binding.

    http://jsfiddle.net/2AKD3/1/

    • btrager

      Thanks. Any thoughts on ways one may be advantageous over the other?

  • maliberty

    This is a nice example. How would you handle setting up a different viewModel per view?

  • rb_al

    This example is really helpful, thanks. I have one question though. I implemented an almost identical routing system for an application, but every time It routes, instead of changing the url to ‘/#’, it looks like ‘/?types=#’ and the console displays the error ‘404 Not Found get /?types=’. Then if I hit ‘back’, the page remains the same and the url looks like ‘/?types=’, and If I hit back again, I end up at my previous page. I don’t understand what ‘?types=’ is, or how I can avoid this. Thanks!

    • bonder

      Your data might be more than just a simple string as shown in this example. Can you post an example?

  • Guest

    Nice ar.ticle. Thank you

  • shemeeermali

    Thank you buddy 🙂

  • 張銀展

    Thanks,good idea