beyond Backbone.JS

you down with MVP? yeah, you know me

by: Ricky Medina

why front end MV*?

  • the modern web is way more complex
  • as browsers have gotten more powerful, it makes more sense for the front end to do some of the heavy lifting
  • application logic needs more consistent structure to avoid Spaghetti code
  • MVC architecture works on server, why not client?

what is Backbone.JS?

from their website:

“… [it] gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.”

  • RESTful javascript front-end MVP framework

what is Backbone.JS?

var app = {};

// model
app.Todo = Backbone.Model.extend({

   urlRoot: '/todo',

   defaults: {title: '', completed: false}
});

// collection
app.TodoList = Backbone.Collection.extend({

   model: app.Todo,

   url: '/todo',

   remaining: function() {
      return this.filter(function(todo) { // built-in underscorejs functions
         return !todo.get('completed');
      });
   },
});

app.todoList = new app.TodoList();

// view
app.AppView = Backbone.View.extend({

   el: 'ul#todo-list',

   initialize: function() {
      var _this = this;

      this.model.fetch({
         success: function(todos) {
            // make list of remaining things to do
            todos.remaining().map(function(todo) {
               _this.$el.append('
  • ' + todo.title + '
  • '); }; )} }); }; }); app.view = new app.AppView(model: app.todoList);
    
    

    downsides

    “application logic is somewhat arbitrarily split between client and server, or in some cases needs to be duplicated on both sides.“

    becomes hard to maintain and develop—especially if anything changes on the back-end

    brainy.io

    solves two problems:

    • repetitive code
      js
      schema: {
         title     : {required: true},
         completed : {required: true}
      }
      perl
      use constant FIELDS => {
      	id        => { numeric => 1, required => 0 },
      	title     => { numeric => 0, required => 1 },
      	completed => { numeric => 0, required => 0 }
      };
    • needing to write an API before prototyping

    brainy will create a RESTful API with various HTTP endpoints based on backbone models and collections!

    what? how?

    brainy.io

    var Todo = Backbone.Model.extend({
       idAttribute: '_id',
       urlRoot: '/todo'
    });
    
    var TodoList = Backbone.Collection.extend({
      url: '/todo',
      model: Todo
    });
    $ curl -X POST -d 'title=discover%20andy's%20weakness' /todo
      {
        "title"     : "discover andy's weakness",
        "completed" : "false",
        "_id"       : "512a40f1163dcb4bce000001"
      }
    $ curl -X GET /todo
      [{
        "title"     : "discover andy's weakness",
        "completed" : "false",
        "_id"       : "512a40f1163dcb4bce000001"
      }]

    brainy.io

    • relies on your application having a particular directory structure
    • all the requisite packages can be installed via npm
      $ npm install brainy-server -g
      $ git clone git@github.com:brainyio/brainy-boilerplate.git
      $ cd brainy-boilerplate/src
      $ brainy-server
    • builds server with express and uses mongoDB for the database layer

    Rendr

    from Airbnb blog:
    “in theory, if we have a JavaScript run-time on the server, we should be able to pull most of this application logic back down to the server in a way that can be shared with the client”

    Rendr

    Rendr

    a “basic Rendr app looks like a hybrid between a standard client-side MVC Backbone.js app and an Express app, with a little Rails convention thrown in.”

    | app
    |-- collections
    |-- controllers
    |-- helpers
    |-- models
    |-- templates
    |-- views
    • Rendr's goal is to let client and server share logic
    • the first call to the server loads in data and serves HTML at which point client-side app kicks in—using the same code

    Thorax

    accomplishes a few things

    • makes Backbone.JS much more suitable for very large-scale applications (developed by Walmart)
    • is more opinionated on views by being integrated directly with Handlebars.js

    Thorax

    data-binding: all properties of the view are accessible to the template

    var view = new Thorax.View({
        greeting: 'Hello',
        template: Handlebars.compile('{{greeting}} World!')
    });
    view.appendTo('body');

    actually allows for child views

    var parent = new Thorax.View({
        child: new Thorax.View(...),
        template: Handlebars.compile('{{view child}}')
    });

    but, really, we should all be using

    more info/bibliography

    • http://arunrocks.com/real-time-applications-and-will-django-adapt-to-it/
    • http://coding.smashingmagazine.com/2012/07/27/journey-through-the-javascript-mvc-jungle/
    • http://brainy.io/
    • http://thoraxjs.org/
    • https://github.com/airbnb/rendr
    • http://nerds.airbnb.com/weve-open-sourced-rendr-run-your-backbonejs-a/
    • http://backbonejs.org/
    • https://github.com/amejiarosario/Backbone-tutorial/blob/master/backbone-tutorial.html
    • http://blog.peterdecroos.com/blog/2013/07/05/thorax-is-awesome/

    end

    by Ricky Medina