MVC pattern in Javascript. An example..

If you are unfortunate enough to be a Java developer who has to develop in Javascript, you will want to start using design patterns, or your javascript code is quickly going to resemble a train wreck.

One of the most important graphical user interface patterns is the MVC (or Model-View-Controller) pattern. In Javascript it is possible to implement the MVC pattern, but it is not as clean as in Java Swing.

First we need to think of an example. Maybe we have a panel or screen that looks something like this :js_mvc3

 

Its basically a one to many relationship of Order to Order Items. You could represent the data part of this with this JSON code :

 

Lets turn now to the View. The View needs to be as dumb as possible. All it is doing is presenting HTML containing a bunch of components, the whole thing then usually wrapped up in a DIV. In the following example the  :

I’ve omitted layout code for the sake of brevity.

Lastly the Controller. The controller contains an aggregate of all events concerning the view. This includes all event handling for the various components on the screen, and the initial load of the screen.

A method to fill the table with data has also been refactored out.

 

The controller you will notice a few things :

  • all GUI components are accesed through the View object
  • event code has been refactored into single methods. However that is not really necessary if the code is only one or two lines
  • implementation of the event methods are omitted for brevity.

Happy coding!

 


Posted in Design Pattern, RIA | Tagged , , , | 2 Comments

2 Responses to MVC pattern in Javascript. An example..

  1. Michael says:

    Is there a very simple implementation code that you can provide? I’m kind of new to MVC and would like to see a very simple page to get it going.

    • asdasa says:

      OrderView = Object.create(Viewable);

      OrderView.createView = function() {

      var nameTextfield = document.createElement(‘input’);

      var table = document.createElement(‘table’);

      var row1 = document.createElement(‘tr’);
      var row2 = document.createElement(‘tr’);
      var row3 = document.createElement(‘tr’);

      var td1 = document.createElement(‘td’);
      var td2 = document.createElement(‘td’);
      var td4 = document.createElement(‘td’);
      var td5 = document.createElement(‘td’);
      var td6 = document.createElement(‘td’);
      var td7 = document.createElement(‘td’);

      row1.appendChild(td1);
      row1.appendChild(td2);

      row2.appendChild(td3);
      row2.appendChild(td4);

      row3.appendChild(td5);
      row3.appendChild(td6);

      table.append(row1);
      table.append(row2);
      table.append(row3);

      this.append(nameTextfield);
      this.append(table);

      }
      I’ve omitted layout code for the sake of brevity.

      Lastly the Controller. The controller contains an aggregate of all events concerning the view. This includes all event handling for the various components on the screen, and the initial load of the screen.

      A method to fill the table with data has also been refactored out.

      OrderController = new Object();

      OrderController.setView = function(pView) {
      this.view = pView;

      this.model = Object.create(TicketViewModel);

      setUpEvents();

      onLoad(this.model);

      };

      OrderController.onLoad = function(data) {

      this.view.idTextfield = data.id;
      this.view.nameTextfield = data.name;
      this.view.typeTextfield = data.type;
      this.view.valueTextfield = data.value;

      setItemData(data)

      }

      OrderController.setItemData = function(data) {

      for(elem in data.items) {

      row1 = document.createElement(‘tr’);

      var td1 = document.createElement(‘td’);
      var td2 = document.createElement(‘td’);

      td1.innerHTML = this.model.items[elem].id;
      td2.innerHTML = this.model.items[elem].desc;

      row1.appendChild(td1);
      row1.appendChild(td2);

      this.view.itemTable.append(row1);
      }
      }

      OrderController.setUpEvents = function() {

      var self = this;

      $(this.view.updateButton).click(function(e) {
      self.update();
      });
      $(this.view.nameTextfield).focusLost(function(e) {
      self.validateNameField();
      });
      $(this.view.exitButton).click(function(e) {
      self.exit();
      });
      };

      OrderController.update = function() {

      //update data to the backend
      };

      OrderController.validateNameField = function() {

      //do some fancy validation on the front end
      };

      OrderController.exit = function() {

      //navigate out of screen.
      };
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      OrderController = new Object();

      OrderController.setView = function(pView) {
      this.view = pView;

      this.model = Object.create(TicketViewModel);

      setUpEvents();

      onLoad(this.model);

      };

      OrderController.onLoad = function(data) {

      this.view.idTextfield = data.id;
      this.view.nameTextfield = data.name;
      this.view.typeTextfield = data.type;
      this.view.valueTextfield = data.value;

      setItemData(data)

      }

      OrderController.setItemData = function(data) {

      for(elem in data.items) {

      row1 = document.createElement(‘tr’);

      var td1 = document.createElement(‘td’);
      var td2 = document.createElement(‘td’);

      td1.innerHTML = this.model.items[elem].id;
      td2.innerHTML = this.model.items[elem].desc;

      row1.appendChild(td1);
      row1.appendChild(td2);

      this.view.itemTable.append(row1);
      }
      }

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

THREE_COLUMN_PAGE