Javascript Front Controller for AJAX Applications

Does anyone know if there are any implementations of a Front Controller in Javascript? This could be really handy for my work on the statzen interface.

Here are the problems I am hoping to solve:

  • The browser’s “back button” doesn’t typically work for AJAX interfaces. The Yahoo! UI Library has a History Manager that solves this problem, but it doesn’t really do it for me.
  • I need to be able to call an event to change a majority of the main area of the screen which may include complex actions such as adding and executing additional javascripts to the document.
  • I need it to work with the tools I am already using (mostly ExtJS)
  • Users should be able to return to the URL that is in the Location Bar and see something similar to the last time they visited that URL.

I think that a Javascript Front Controller can do all of these things. First up there is the back button. YUI’s History Manager uses named anchor links (i.e. adding #someaction to the URL). This method allows you to change the URL in the Location Bar without reloading the entire page. This also solves the last problem of having persistent URLs.

The Front Controller would allow you to match a named anchor string (or a regex match) and tie that to a function call (possibly using match variables from the regex). Using an onload function the Front Controller would process new requests and call the function that would build the page appropriately. Then you would be able to further call new actions through the front controller. When the Front Controller was called it would check the named anchor string against location.hash and update it if necessary. The Front Controller would then call the appropriate function.

So, let’s say someone went to http://example.com and clicked which was a blog. They then clicked to view a post which called something like FrontController.load(‘#post-1234′). the Front Controller would then change the Location Bar to http://example.com/#post-1234. The Front Controller would then check it’s “routes” hash and see that it should send the post id to the viewPost method like viewPost(1234). This could then make an AJAX call to retrieve the post as JSON and possibly load a new JavaScript that knew how to build (template) the post. If the user later returned to http://example.com/#post-1234 they would see the same content that they saw before.

The Front Controller would work with whatever tools you wanted to use no matter how complex because it just calls a method and passes arguments to it. There could even be a method for JIT script loading (especially if the JavaScript “controllers” followed a simple naming convention (hell, even additional routes could be pulled down when needed). Because the controller scripts would be cached by the browser the second post would load faster than the first.

It looks like there are some Javascript MVC frameworks out there, but that seems like overkill to me. Especially since the libraries I am using already have an idea about Models (JSON) and views (components, widgets, etc).

I don’t really want to start developing frameworks again, but I do hate repeating myself. Still, I am really hoping someone out there already knows about something that does this.

update: As I started playing with a proof of concept I realized the YUI solution to the back button is much more complex than I initially thought (then I found this really great post about what it took to create it). Hopefully I didn’t think about that because it is late. Anyway, I don’t want to duplicate the YUI work. As I look a little deeper I must say that the YUI History Manager is a mighty fine piece of work. I think I will use YUI History Manager to create my simple Front Controller.

3 Comments Short URL , , ,

3 Responses to “Javascript Front Controller for AJAX Applications”

  1. Jack Slocum February 11, 2009 at 3:15 pm #

    The next version of Ext JS (2.2) will have an easy to use History manager. It's already in SVN.

    Regards,
    Jack

  2. jaxn February 11, 2009 at 3:15 pm #

    Very cool. Thanks for the tip Jack.

    How stable is trunk?

  3. Greg Burghardt April 14, 2011 at 12:53 pm #

    I’ve been searching for something similar, and ended up writing my own code. It’s broken up into two main pieces.

    First, we have a Router, which takes a string, parses it out into a Route object, which is used to call methods on “controllers” registered with the Router. Multiple “controllers” can register on the same route Id.

    Secondly, I detest writing code to grab a DOM node, attach a click handler, and also bind the callback to a context so “this” points to a JavaScript object rather than the DOM node. For this I created a DOMEventRouter.

    Basically, there is one click handler on the document object. Clicking on something causes the DOMEventRouter to start at the target element, look for a data-route-click attribute on that node, process that route, and then climb the DOM tree up to the document object all the while looking for data-route-click attributes.

    data-route-click=”post/view/1234″

    Then you need to register an object with the Router using a route Id, in this case “post”:

    Router.registerController(“post”, postController);

    Then any object registered with the Router for the “post” route Id needs a “view” method defined in order to respond to this route: “post/view/1234″

    postController.view = function(id) { … }

    It works well. The only thing I haven’t wired in is the “history”. The Router itself could append the route string to the anchor of the address bar, and then ping that anchor every so many seconds to look for changes. That should be easy to put in.

    On top of that, you aren’t necessarily tied to the DOM.

    Router.processRoute(“{route Id}/{method name}/arg1/arg2/… /argN”);

    Everything after the {method name} gets parsed out into arguments passed to a JavaScript function, plus the last two arguments of a route that originates from the DOMEventRouter are the DOM node that had the data-route-click attribute and the browser event object.

    Check out the code demos below. You’ll need to clone the whole Git repository and view the pages in the test/router directory. I think the combination of the Router and DOMEventRouter will get you what you want. I just need to wire up the functionality in Router to change the anchor in the address bar and then detect changes in the anchor to support the back button.

    Code demo:
    https://github.com/gburghardt/JsLib/tree/master/test/router

    Full Git Repository:

    https://github.com/gburghardt/JsLib/

Leave a Reply