views:

705

answers:

4

Hey all, I'm looking at building an ajax-heavy site, and I'm trying to spend some time upfront thinking through the architecture.

I'm using Code Igniter and jquery. My initial thought process was to figure out how to replicate MVC on the javascript side, but it seems the M and the C don't really have much of a place.

A lot of the JS would be ajax calls BUT I can see it growing beyond that, with plenty of DOM manipulation, as well as exploring the HTML5 clientside database. How should I think about architecting these files? Does it make sense to pursue MVC? Should I go the jquery plugin route somehow? I'm lost as to how to proceed and I'd love some tips. Thanks all!

+5  A: 

I've made an MVC style Javascript program. Complete with M and C. Maybe I made a wrong move, but I ended up authoring my own event dispatcher library. I made sure that the different tiers only communicate using a message protocol that can be translated into pure JSON objects (even though I don't actually do that translation step).

So jquery lives primarily in the V part of the MVC architecture. In the M, and C side, I have primarily code which could run in the stand alone CLI version of spidermonkey, or in the serverside rhino implementation of javascript, if necessary. In this way, if requirements change later, I can have my M and C layers run on the serverside, communicating via those json messages to the V side in the browser. It would only require some modifications to my message dispatcher to change this though. In the future, if browsers get some peer to peer style technologies, I could get the different teirs running in different browsers for instance.

However, at the moment, all three tiers run in a single browser. The event dispatcher I authored allows multicast messages, so implementing an undo feature now will be as simple as creating a new object that simply listens to the messages that need to be undone. Autosaving state to the server is a similar maneuver. I'm able to do full detailed debugging and profiling inside the event dispatcher. I'm able to define exactly how the code runs, and how quickly, when, and where, all from that central bit of code.

Of course the main drawback I've encountered is I haven't done a very good job of managing the complexity of the thing. For that, if I had it all to do over, I would study very very carefully the "Functional Reactive" paradigm. There is one existing implementation of that paradigm in javascript called flapjax. I would ensure that the view layer followed that model of execution, if not used specifically the flapjax library. (i'm not sure flapjax itself is such a great execution of the idea, but the idea itself is important).

The other big implementation of functional reactive, is quartz composer, which comes free with apple's developer tools, (which are free with the purchase of any mac). If that is available to you, have a close look at that, and how it works. (it even has a javascript patch so you can prototype your application with a prebuilt view layer)

The main takaway from the functional reactive paradigm, is to make sure that the view doesn't appear to maintain any kind of state except the one you've just given it to display. To put it in more concrete terms, I started out with "Add an object to the screen" "remove an object from the screen" type messages, and I'm now tending more towards "display this list of objects, and I'll let you figure out the most efficient way to get from the current display, to what I now want you to display". This has eliminated a whole host of bugs having to do with sloppily managed state.

This also gets around another problem I've been having with bugs caused by messages arriving in the wrong order. That's a big one to solve, but you can sidestep it by just sending in one big package the final desired state, rather than a sequence of steps to get there.

Anyways, that's my little rant. Let me know if you have any additional questions about my wartime experience.

Breton
This is a very intriguing solution and I'd love to see more. Do you have any code examples that I could see?
Dustin Martin
@Dustin Martin unfortunately it's all under NDA, not open sourced code. sorry.
Breton
+3  A: 

At the risk of being flamed I would suggest another framework besides JQuery or else you'll risk hitting its performance ceiling. Its ala-mode plugins will also present a bit of a problem in trying to separate you M, V and C.

Dojo is well known for its Data Stores for binding to server-side data with different transport protocols, and its object oriented, lighting fast widget system that can be easily extended and customized. It has a style that helps guide you into clean, well-divisioned code – though it's not strictly MVC. That would require a little extra planning.

Dojo has a steeper learning curve than JQuery though.

More to your question, The AJAX calls and object (or Data Store) that holds and queries this data would be your Model. The widgets and CSS would be your View. And the Controller would basically be your application code that wires it all together.

In order to keep them separate, I'd recommend a loosely-coupled event-driven system. Try to directly access objects as little as possible, keeping them "black boxed" and get data via custom events or pub/sub topics.

mwilcox
I don't know why you should be flamed. Your suggestions are quite pragmatic. jQuery is a wonderful library, but it doesn't seem like it was designed with this kind of application in mind. It's more suited to lightweight use doing simple effects, or providing packaged up ui widgets that are simple to deploy on an existing static type webpage. That said, I used jquery to get around the typical cross browser dom gruntwork you'd have to do without a library.
Breton
+1  A: 

There are a few JavaScript MVC frameworks out there, this one has the obvious name: http://javascriptmvc.com/

Doomspork
+3  A: 

JavaScriptMVC (javascriptmvc.com) is an excellent choice for organizing and developing a large scale JS application.

The architecture design is very practical. There are 4 things you will ever do with JavaScript:

  1. Respond to an event
  2. Request Data / Manipulate Services (Ajax)
  3. Add domain specific information to the ajax response.
  4. Update the DOM

JMVC splits these into the Model, View, Controller pattern.

First, and probably the most important advantage, is the Controller. Controllers use event delegation, so instead of attaching events, you simply create rules for your page. They also use the name of the Controller to limit the scope of what the controller works on. This makes your code deterministic, meaning if you see an event happen in a '#todos' element you know there has to be a todos controller.

$.Controller.extend('TodosController',{
   'click' : function(el, ev){ ... },
   '.delete mouseover': function(el, ev){ ...}
   '.drag draginit' : function(el, ev, drag){ ...}
})

Next comes the model. JMVC provides a powerful Class and basic model that lets you quickly organize Ajax functionality (#2) and wrap the data with domain specific functionality (#3). When complete, you can use models from your controller like:

Todo.findAll({after: new Date()}, myCallbackFunction);

Finally, once your todos come back, you have to display them (#4). This is where you use JMVC's view.

'.show click' : function(el, ev){ 
   Todo.findAll({after: new Date()}, this.callback('list'));
},
list : function(todos){
   $('#todos').html( this.view(todos));
}

In 'views/todos/list.ejs'

<% for(var i =0; i < this.length; i++){ %>
   <label><%= this[i].description %></label>
<%}%>

JMVC provides a lot more than architecture. It helps you in ever part of the development cycle with:

  • Code generators
  • Integrated Browser, Selenium, and Rhino Testing
  • Documentation
  • Script compression
  • Error reporting
Justin Meyer