Skip to main content

MVP pattern with Javascript framework?



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.





Source: Tips4all

Comments

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


    Event Handling
    DOM manipulation
    Server communication (AJAX calls)


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


    EventHandling = Presenter
    DOM Manipulation = View
    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 MVC 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

    ReplyDelete
  2. Take a look at knockout.js which is a MVVM framework for your web pages. It provides a really beautiful and easily extensible framework for linking a model and a view in a loosely coupled fashion.

    ReplyDelete
  3. Check out angular project at http://angularjs.org/ and feel free to ask any question at mailing group.

    It's designed to work well together with jQuery.
    Very useful for writing TESTABLE MVC JS applications.

    ReplyDelete
  4. I know this question is old, but I think it is worth mention here. My vote goes to Backbone.js. Even docs says it is MVC, I would say it is MVP.


    VIEW = html template (jQuery.template)
    MODEL = Backbone.Model
    PRESENTER = Backbone.View ( layer between your view-tempate and how to bound data to it, and more thins you can do) and what is best you can use in render method couple views (html templates) or switch which to use...


    and what is best you still have controller


    CONTROLLER = Backbone.Controller


    Alternative could be as @JoshRivers mentioned, knockoutJS but my personal opinion is that view template is overwhelmed with binding stuff.

    And last note. Thing is View as V from either MVC or MVP is something which can be built from your template without coding it, make good HTML template parser and you are good to go :) Believe me, convention is your friend.

    ReplyDelete
  5. Check PureMVC out. They have also port to JavaScript.

    ReplyDelete
  6. Seems googles GWT use MVP: http://code.google.com/events/io/2010/sessions/architecting-production-gwt.html

    ReplyDelete
  7. I've actually implemented an MVC like approach in my last JavaScript project. I'm with you, it wasn't easy to determine what goes in the view and what in the controller, there is a lot of gray area.

    This was my approach:


    Model - the data from the server came in a nice JSON object, so I left it as is.
    View - tried to keep it "dumb" with dry UI functionality. In other words, it provided an API that allows changing any of the visual aspects. For example - setting the size, setting the title, changing colors, etc.
    Controller - if the view is the puppet, then the controller is the puppet master. It was in charge of fetching data from the server and pulling all the right strings to give life to the UI. For example - in case of an error, use the viewer to display an error message, or when the data arrives parse it and then display it via the viewer.


    Note - I decided to keep some internal logic in the view after all since it felt practical and independent of the controller. For example, handling tab overflow (what to do when there are too many tabs to display and not enough space). Not sure if it was the right decision in terms of MVC, because I read a guideline somewhere that the view should not call its own methods. However, so far so good.

    Hope this helps, and best of luck.

    ReplyDelete
  8. Another one: http://javascriptmvc.com/

    Never used it myself, but maybe it will help you out.

    EDIT: Just a note that Ext JS v. 4.0 will ship in Q1 2011 with new functionality for generating MVC project structures and scaffolding on the client. I haven't yet tried it, but the preview I saw looked pretty good. Should be interesting to anyone interested in MV[C|P] on the client.

    ReplyDelete
  9. @Yanick "Usually, MVP is on the client, while MVC is on the server."

    I think you misunderstand MVP (Model View Presenter). This pattern is very similar to MVC (Model View Controller) in that you attempt to separate concerns in your application. The main difference is how requests are handle as they are received. MVP exists because ASP.NET WebForms, which is a server side tech, cannot handle a pure MVC model. Check out this post for a good comparison.

    As far as using it (or even MVC for that matter) in your JavaScript code, I think this is the wrong pattern for the job. I would also say that if you fell you need to use one of these patterns then you are over complicating your frontend but that's a discussion for another post. If you are dead set on using this type of pattern then go with MVC since MVP is really a workaround to get MVC like separation in ASP.NET.

    ReplyDelete

Post a Comment

Popular posts from this blog

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.