JavaScriptMVC: jQueryMX

Contents

  1. Introduction
  2. $.Class
  3. $.Controller
  4. $.Model
  5. $.View
  6. Conclusion
  7. Resources

1. Introduction

JavaScriptMVC (JMVC) is a frontend development framework based on jQuery. Besides MVC libraries it provides utilities for testing, dependency management and the generation of documentation. With these useful components you will be able to build a maintainable, error-free, lightweight application in the shortest amount of time.

JMVC is divided into the following sub-projects

  • jQueryMX       – a set of jQuery plugins
  • StealJS          – dependency management
  • FuncUnit        – testing framework
  • DocumentJS   – documentation generation

To limit the scope of this article only jQueryMX is discussed, the MVC part of JMVC

jQueryMX is a group of jQuery extensions, the building blocks of MVC. Although these extensions are packaged toghether, you can use them individually too. With the Download Builder you can select the extensions you need.

2 $.Class

This extension simulates class-oriented inheritance, because JavaScript uses a class-free prototype-oriented inheritance approach. To create a class you can use the following syntax

1
$.Class(ClassName,  { /* static members */ }, { /* instance members */ }) ;

 

This is just the basics, it’s real power is inheritance and namespacing

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$.Class('com.example.Bar', { /* static members */ },  {
      init: function(name){
           this.name = name ;
       },
      toString: function() {
            return this.name ;
       },
});

com.example.Bar('com.example.Foo', { /* static members */ }, {
      toString: function() {
            return this._super() + ' Rocks' ;
       }
}) ;

var obj = new com.example.Foo('JavaScriptMVC') ;
alert(obj.toString()) ; // -> JavaScriptMVC Rocks

( Execute the example )

This is a Class inheritance example, demonstrating function overriding. First the Bar class is created and namespaced with com.example. In complex environments namespaces are crucial, because without them you would pollute your global namespace and risk getting nasty conflicts, with the result of timeconsuming bug hunts.

Furthermore, the Foo class inherits from Bar and overrides the toString method.

3 $.Controller

With $.Controller you can write widgets like sliders, tabs or grids. It simplifies widget development, especially event management; on() and off() are called behind the scene. Take a look at the following example, it shows how easy it is to use events

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
$.Controller('MyTestWidget', { // static members
        count: 0
    }, { // prototype members
        init: function(rawEl, rawOptions) {
            $('.spot:first').clone().html('widget ' + (++this.Class.count))
                                          .appendTo(this.element) ;
        },
        mousemove: function(el, ev) { 
           el.css('background-color', 'red') ;
        }, 
        '{window} .reset click': function(el, ev) {
            this.element.css('background-color', '') ;
        },
        '.spot click': function(el, ev) {
            el.fadeOut().fadeIn() ;
        }
   }) ;

$('.widget').my_test_widget() ;

( Execute the example )

Binding events always apply to elements inside the widget-element. You can change this scoping feature by prepending the event/selector definition by a DOM object surrounded by curly braces (see line 12)

4 $.Model

This extension provides a very powerful and robust data layer, with features like JSON/REST support and the Observable pattern implementation. Here is an example of how to define and use a Model

1
2
3
4
$.Model( 'Todo' ) ; // define the Todo model

var todo = new Todo( { name: 'Bar' } ) ;
todo.save(successHandler, ErrorHandler )   

 

Saving the data to a backend is an asynchronious task, so you have to use callback functions. But you can also use the Deferred returned by the save() function. Finally, with the Observable pattern monitoring this Todo model isn’t a big challenge too

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$.Controller('Todos',{
  "{Todo} created" : function(Todo, ev, todo) {
      // do something 
  }
}) ;
    
$.Model( 'Todo' ) ;

var todo = new Todo({ name: 'Bar' }) ;
todo.bind('name', function(event, newValue) {
    // do something here too
}) ;

( Demo )

The ‘created’ event is fired when a new Todo instance is created/saved. But a controller can also listen to updated and destroyed events. It is also possible to define your own custom events (see the demo). For attribute changes you bind an event handler to the instance itself (line 10).  

5 $.View

Working with template engines is very powerful, but with $.View it gets even better. For example, the $.View extension overwrites the jquery modifiers so now you can do things like

1
$("#bar").html('atemplate.tmpl',data)

 

With the modifications made by $.View,  the html() modifier loads the template file, executes the template engine and inserts the result. $.View comes pre-packaged with 4 different template engines, which you can choose from using the Download Builder. But $.View uses Deferreds too, so why not load the data at the same time

1
2
3
4
$('#bar').html('atemplate.tmpl',{
  users : User.findAll(),
  todos: Todo.findAll()
})

 

6. Conclusion

This article is far from a complete reference, but consider it a teaser, providing some insights of what JMVC is and can do. The jQueryMX extensions give your application a good maintainable structure and all its features will definitely boost software development. Because of its good structure, this framework perfectly fits together with frameworks that lag this capability. A good example I think would be jQueryMobile.

7. Resources

 

Comments are closed.