views:

561

answers:

7

How is your javaScript code organized? Does it follow patterns like MVC, or something else?

I've been working on a side project for some time now, and the further I get, the more my webpage has turned into a full-featured application. Right now, I'm sticking with jQuery, however, the logic on the page is growing to a point where some organization, or dare I say it, "architecture" is needed. My first approach is "MVC-ish":

  • The 'model' is a JSON tree that gets extended with helpers
  • The view is the DOM plus classes that tweak it
  • The controller is the object where I connect events handling and kick off view or model manipulation

I'm very interested, however, in how other people have built more substantial javaScript apps. I'm not interested in GWT, or other server-oriented approaches... just in the approach of "javaScript + <generic web service-y thingy here>"

Note: earlier I said javaScript "is not really OO, not really functional". This, I think, distracted everyone. Let's put it this way, because javaScript is unique in many ways, and I'm coming from a strongly-typed background, I don't want to force paradigms I know but were developed in very different languages.

+5  A: 

..but Javascript has many facets that are OO.

Consider this:

var Vehicle = jQuery.Class.create({ 
   init: function(name) { this.name = name; } 
});

var Car = Vehicle.extend({ 
   fillGas: function(){ 
      this.gas = 100; 
   } 
});

I've used this technique to create page-level javascript classes that have their own state, this helps keep it contained (and I often identify areas that I can reuse and put into other classes).

This is also especially useful when you have components/server controls that have their own script to execute, but when you might have multiple instances on the same page. This keeps the state separate.

Ben Scheirman
A: 

Not 100% sure what you mean here, but I will say that after doing ASP.NET for the last 6 years, my web pages are now mostly driven by JavaScript once the basic page rendering is done by the server. I use JSON for everything (have been for about 3 years now) and use MochiKit for my client-side needs.

By the way, JavaScript is OO, but since it uses prototypical inheritance, people don't give it credit in that way. I would also argue that it is functional as well, it all depends on how you write it. If you are really interested in functional programming styles, check out MochiKit - you may like it; it leans quite a bit towards the functional programming side of JavaScript.

Jason Bunting
+1  A: 

MochiKit is great -- and was my first love, so-to-speak, as far as js libraries go. But I found that while MochiKit has very expressive syntax, it didn't feel nearly as comfortable to me as Prototype/Scriptaculous or jQuery did for me.

I think if you know or like python, then MochiKit is a good tool for you.

Ben Scheirman
+1  A: 

Thank you all kindly for your answers. After some time, I'd like to post what I've learned so far.

So far, I see a very large difference the approach using something like Ext, and others like JQuery UI, Scriptaculous, MochiKit, etc.

With Ext, the HTML is just a single placeholder - UI goes here. From then on, everything is described in JavaScript. DOM interaction is minimized under another (perhaps stronger) API layer.

With the other kits, I find myself starting by doing a bit of HTML design, and then extending the DOM directly with snazzy effects, or just replacing the form input here, an addition there.

The major differences start to happen as I need to deal with event handling, etc. As modules need to "talk" to each other, I find myself needing to step away from the DOM, abstracting it away in pieces.

I note that many of these libraries also include some interesting modularization techniques as well. A very clear description is contributed on the Ext website, which includes a fancy way to "protect" your code with modules.

A new player I haven completely evaluated is Sproutcore. It seems like Ext in approach, where the DOM is hidden, and you mostly want to deal with the project's API.

Tristan Juricek
+1  A: 

Tristan, you will find that when you try to architecture JavaScript as an MVC application it tends to come up short in one area -- the model. The most difficult area to deal with is the model because the data does not persist throughout the application, and by nature the models seem to change on the client-side pretty consistently. You could standardize how you pass and receive data from the server, but then at that point the model does not really belong to JavaScript -- it belongs to your server-side application.

I did see one attempt awhile back where someone created a framework for modeling data in JavaScript, much like the way SQLite belongs to the application. It was like Model.select( "Product" ) and Model.update( "Product", "Some data..." ). It was basically an object notation that held a bunch of data to manage the state of the current page. However, the minute you refresh, all that data is lost. I'm probably off on the syntax, but you get the point.

If you are using jQuery, then Ben's approach is really the best. Extend the jQuery object with your functions and properties, and then compartmentalize your "controllers". I usually do this by putting them into separate source files, and loading them on a section-by-section basis. For instance, if it were an e-commerce site, I might have a JS file full of controllers that handle functionality for the checkout process. This tends to keep things lightweight and easy to manage.

hal10001
+1  A: 

Just a quick clarification.

It is perfectly feasible to write GWT apps that are not server-oriented. I am assuming that from Server-Oriented you mean GWT RPC that needs java based back-end.

I have written GWT apps that are very "MVC-ish" on the client side alone.

  • The model was an object graph. Although you code in Java, at runtime the objects are in javascript with no need of any JVM in either client or server-side. GWT also supports JSON with complete parsing and manipulation support. You can connect to JSON webservices easily, see [2] for a JSON mashup example.
  • View was composed of standard GWT widgets (plus some of our own composite widgets)
  • Controller layer was neatly separated from View via Observer pattern.

If your "strongly-typed" background is with Java or similar language, I think you should seriously consider GWT for large projects. For small projects I usually prefer jQuery. Upcoming GWTQuery that works with GWT 1.5 may change that though not in near future because of abundance of plugins for jQuery.

Tahir Akhtar
+1  A: 

JavaScriptMVC is a great choice for organizing and developing a large scale JS application.

The architecture design very well thought out. 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