MVP pattern with Javascript framework?

CriosR picture CriosR · Jul 9, 2009 · Viewed 18.7k times · Source

Has anyone been able to implement the MVP model with any javascript frameworks? I'm having trouble figuring out how to have the presenter -> view inversion from server code to javascript. I have some ideas, but kind of hackish and would like to see what others are doing.

Answer

Neovibrant picture Neovibrant · May 27, 2011

The main goal with MVP is decoupling of different aspects in the code. Normally, in JavaScript, there are 3 major such aspects:

  1. Event Handling
  2. DOM manipulation
  3. Server communication (AJAX calls)

For each of these concerns, there's a corresponding term from MVP:

  1. EventHandling = Presenter
  2. DOM Manipulation = View
  3. AJAX calls = Model

Since indeed it is not always simple to implement the 3 aspects, an EVENT BUS may come in handy. This bus should be a singleton and all the events, raised in various context should be published on the bus. The Presenter needs to register to its events and react accordingly when events happen.

Here is how it would work:

First thing that happens is the page load. Listen to this using the normal event model or jQuery or whatever is convenient. Create the Model, the View and the Presenter. The Presenter needs to hold the View and Model instances since he's gonna use them.

var model = new Model();
var view = new View();
var presenter = new Presenter(model, view);

Remember that Presenter is the event handler so the bus should know about it and route events to it for handling:

bus.registerHandler(presenter);

The first event is the "init", which means the page has loaded and the MVP objects are all set:

bus.init(); // call this yourself

This would trigger something in the Presenter, like a function. I prefer the on... naming convention, in this example presenter.onInit(). This gives a chance to install UI listeners:

// in the Presenter
onInit: function() {
  view.addSubmitListener();
  view.addWhateverListener();
  ...
}

// in the View (using jQuery)
addSubmitListener: function() {
  $("#submitButton").click(function() {
    var formData = ...
    bus.submit(formData); // publish an event to the bus
  });
}

When the Submit button is clicked the bus.submit(formData) is called and this will route it to the handler -- presenter.onSubmit(formData):

// in the Presenter
onSubmit: function(formData) {
  model.postForm(formData, function(data) {
    // handle the response
    view.updateSomething(data);
  });
}

And so on... The entire trick is binding the bus to the presenter and then you're in the loop.

HTH