JS and Patterns

Examples

Learn more...

Tutorial

This page present a simple example of MVC applied. MVC stands for Model-View-Controller. All web page functionalities are divided in separated components, these components collaborates in order to provide a the web-app behaviour/view. Although it seems that it is more complex to build, it structures components with high cohesion and low coupling, so in large term, it is easier to add and change behaviour/views.

Model

Model is basically data. It can be something that can be read from the server, user preferences, a list of things, a thing, information about which button is pushed, etc. We can see it as just JSON:

{ "name": "John", "surname": "Smith", }

In addition, models also can have functions to provide some queries:

{ name: 'John', surname: 'Smith', getFullName: function() { return this.name +' '+ this.surname; }, }

Models can be categorized by kind, each kind of model has its own fields and supporting functions. We should create a component to handle each kind of model. An example of model should be:

function User(data) { this.name = data.name; this.surname = data.surname; } User.getFullName = function() { return this.name +' '+ this.surname; };

When a new model is created it just is instanced from the model. Example:

// create var johnSmith = new User({ name: 'John', surname: 'Smith', }); // and use console.log(johnSmith.getFullName());

Full examples are:

Note: in jQuery there is an auxiliary class because models needs to be watched

View

View is basically html. View is what is shown to the user, and what the user can use to interact. View presents model information (watches models for changes), and captures events so some kind of interaction can be performed on model.

<div> <span class="bind-user-name"></span><br> <span class="bind-user-surname"></span><br> <button class="action-send-hello"></button> </div>

A plain html needs a Javascript to link models and events to the html:

function UserHelloView(data) { $.extend(this, data); } UserHelloView.prototype.link = function (dom) { var view = this; // update html with changes in the user view.user.observe(function(user) { $('.bind-user-name').text(user.name); $('.bind-user-surname').text(user.surname); }); // listen for events $('.action-send-hello').click(function() { view.sendHello(); }); },

The view Javascript part has an interface which can be used directly by controllers. The view itself never will use a controller directly (only via callbacks, like sendHelo). Look to View Controllers for more information.

Full examples are:

Controllers

Controllers are everything else. Is what prepares views, loads data, saves values, handles events reactions, etc. Usually they are confused as simple view controllers, but if you want to have high cohesion and low coupling you should consider specialized kinds of controllers: View Controllers, Flow/Route Controllers, Storage/Service Controllers, ...

View Controllers

A view controller is a controller that instances a view, sets up this view, and shows it to the user. This is how the controller sets up a view (remember that view provides an interface):

// controller code setting up a view view = new UserHelloView(); view.user = UserService.get(userId); view.sendHello = function() { UserWaver.sendHello(userId); }; view.link(currentDom);

View controllers should only use Storage/Service controllers and views. About models they should know as little bit as possible.

Full examples are:

Storage/Service Controllers

Services and Storage Controllers deals primarily with data. They are responsible to load and save data. They are a centric point to manage each kind of data or application behaviour. Data can be stored in the client, just be a variable, or recovered and stored in an external server (service). When the application need to deal with some data, storage/service controllers make all loads and saves. It usually uses promises to return data, so it do not require a predefined callback to know when data is available.

var UserService = { get: function() { return $http({method: 'GET', url: '/api/me'}).then(function(response) { if (response.status >= 300) { throw response; } return response.data; }); }, ... };

Storage/Service controllers should only use Models, and in some ocasions other storage/service controllers (for example: a controller that tries to load data from an IndexedDb and if it is not present from a remote service).

Stubs of examples are:

Flow/Route Controllers

This controllers controls the flow of the application. If case of single-page apps (with multiple routes) they are also route controllers. They decide what to activate in each situation. They request to load some data (call storage/service controllers) and starts views controllers with predefined data. They have a global vision of the app.

document.addEventListener('load', function() { viewControllers.forEach(function(viewController) { viewController.launch(); }); });

Stubs of examples are: