a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design.source: Wikipedia :: Software design pattern
Model-View-Controller is an architectural Design Pattern.
MVC isolates domain logic from the user interface, promoting
The model is any of the logic or the database or any of the data itself. -Terence Parr
The controller decides what the user's input was, how the model needs to change as a result of that input, and which resulting view should be used. - Jeff Atwood
MVC has traditionally been implemented in many backend languages; including:






We would like to be able to do the following:
Built in Bacbone.js 0.5.3 and Ruby on Rails 3.1.1. So what is Backbone.js?
Backbone supplies structure to JavaScript-heavy applications ...
Underscore is a [utility] library ... that provides a lot of the functional programming support ... without extending any of the built-in JavaScript objects.
Zepto.js is a minimalist JavaScript framework for modern web browsers, with a jQuery-compatible syntax.
Source: http://documentcloud.github.com/backbone/
Source: http://documentcloud.github.com/underscore/
Source: http://jquery.com/
Source: http://zeptojs.com/
You extend Backbone.Model with your domain-specific methods, and Model provides a basic set of functionality for managing changes; conversions, validations, computed properties and access control.
/**
@description An example of a Model in Backbone.js
@url http://documentcloud.github.com/backbone/#Model
*/
var Model = Backbone.Model.extend({
// Restful URL of the Model e.g. "/[urlRoot]/id"
'urlRoot': '/model'
// Default attribute values
'defaults': {
'length': 0,
'width': 0,
'height': 0
},
/**
@constructor
*/
'initialize': function () {
},
/**
@function
@description Validates your attributes before a set or save
*/
'validate': function () {
// do not return anything if attributes are valid
}
});
var model = new Model({
'length': 0,
'width': 0,
'height': 0
});
model.set('length', 1);
----
model.get('length');
Source: http://documentcloud.github.com/backbone/#Model
The general idea is to organize your interface into logical views, backed by models, each of which can be updated independently when the model changes, without having to redraw the page.
/**
@description An example of a View in Backbone.js
@url http://documentcloud.github.com/backbone/#View
*/
var View = Backbone.View.extend({
'events': {
'click a': 'clickHandler'
},
/**
@constructor
*/
'initialize': function () {
},
/**
@function
@description Override this function with your code that renders the view template from model data, and updates this.el with the new HTML.
@returns {View}
*/
'render': function () {
// Allows for chained calls
return this;
},
/**
@event
@description Handles the click even on all anchor tags.
@param e Click Event
*/
'clickHandler': function (e) {
e.preventDefault();
e.stopPropagation();
}
});
Backbone views are almost more convention than they are code — they don't determine anything about your HTML or CSS for you, and can be used with any JavaScript templating library.
The View class can also be thought of as a kind of controller, dispatching events that originate from the UI, with the HTML template serving as the true view.
new View({
'el': document.getElementById('item')
});
var view = new View();
----
'initialize': function () {
this.render();
},
----
view.render();
Source: http://documentcloud.github.com/backbone/#View
Collections are ordered sets of models.
/**
@description An example of a Collection in Backbone.js
@url http://documentcloud.github.com/backbone/#Collection
*/
var Collection = Backbone.Collection.extend({
//Override this property to specify the model class that the collection contains
'model': Model,
/**
@constructor
*/
'initialize': function () {
}
});
//initialize your model
var model = new Model({
'length': 0,
'width': 0,
'height': 0
});
//create a new collection
var coll = new Collection();
//add model to collection
coll.add(model);
Source: http://documentcloud.github.com/backbone/#Collection
<script src="libs/LAB.min.js">
<script>
$LAB
//libs
.script('libs/jquery-1.6.4.min.js" %>').wait()
.script('libs/underscore-min.js" %>').wait()
.script('libs/backbone.js" %>').wait()
//models
.script('flmstrp/model/FilmModel.js" %>').wait()
//collections
.script('flmstrp/collection/FilmCollection.js" %>').wait()
//views
.script('flmstrp/view/FilmView.js" %>').wait()
.script('flmstrp/view/ModalView.js" %>').wait()
.script('flmstrp/film.config.js" %>').wait()
.script('flmstrp/film.js" %>').wait()
.script('flmstrp/film.personalfilms.js" %>').wait()
.script('flmstrp/film.modal.js" %>').wait( function () {
Film.PersonalFilms.init();
Film.Modal.create();
});
</script>
var Film = {}; //Global utils, attributes here
Film.views = {}; //personalView
Film.models = {}; //personalFilmModels
Film.collections = {}; //personalFilmCollection
Simple: It calls a JavaScript function for injecting html contents on the client side. It can also interpolate and/or evaluate expressions using regex.
<script type="text/template" id="myscript">
<ul>
<% _.each(models, function (model) {
<li>
<h2><%= model.name %></h2>
<p><%= model.description %></p>
</li>
})%>
</ul>
</script>
var models, results;
models = [model1, model2, model3];
results = _.template($('#myscript').html(), models);
$('#container').append(results);
You can change your interpolation settings like so:
_.templateSettings = {
interpolate : /\{\{(.+?)\}\}/g,
evaluate : /\{\{\=(.+?)\}\}/g,
};
This allows you to use {{ }} instead of <% %>
<script type="text/template" id="myscript">
<ul>
{{#models}}
<li>
<h2>{{name}}</h2>
<p>{{description}}</p>
</li>
{{#models}}
</ul>
</script>
var results, html;
html = $('#myscript').html();
results = Mustache.to_html(html, { 'models': [model1, model2, model3] });
$('#container')
.append(results);
To disable escaping in your template - use triple mustaches like so:
{{{unescaped_variable}}}
The following characters are escaped int he curly braces:
& \ " ' < >
<script type="text/x-handlebars-template" id="myscript">
<ul>
{{#each models}}
<li>
<h2>{{this.name}}</h2>
<p>{{this.description}}</p>
</li>
{{/each}}
</ul>
</script>
var template, results;
template = Handlebars.compile($('#myscrip').html());
results = template( {'models': [model1, model2, model3]} );
$('#container')
.append(results);
Use helpers to process your information, helping you keep your logic outside the template:
Handlebars.registerHelper('calculate_total', function() {
return "" + this.price * this.order_amount + "";
});
You would then use this help, like so:
<ul>
{{#each items}}
<li>Total: {{calculate_total}}</li>
{{/each}}
</ul>
/
#