MVC in JavaScript
In order to understand MVC in JavaScript, I will first explain briefly about MVC - what is the purpose of each component in MVC, how this pattern is becoming popular and how you can implement it using JavaScript? At the end of this article, I will be sharing one dummy example (task checker) that I made using MVC in JavaScript.
1. Model
It simply means data. Any datamember
or any datastructure
which will be used for storing data will be called model. Moreover, the way to insert
/delete
data or other methods used for performing different operations on data will be written in model only. For example, an employee
object can have employee name, id, salary, work experience, etc. Here, employee
object is a model since it is actual data.
2. View
It is that part of MVC which we see on screen. As the name suggests, View involves a User Interface that will be used for displaying data. This data will be taken from model. It means, every view object contains a model object. For example, a table on UI that shows employee
data so here this table is created using view object.
3. Controller
It is that part of MVC which makes use of both view and model.
A general event binding is written inside controller. When application starts, controller initiates the application where general events are binded. For example, on click of a button, employee
object should be created. This event binding can be written inside controller.
Note: In some cases, instead of writing such a code inside controller, you can create a separate view and write the same code inside that view. Therefore, 'C
' in MVC is always a point of discussion.
4. Collection
Sometimes, you want multiple models stored in a single entity. In such a case, collection is very useful. I will explain how to create collection in the example below.
Why MVC?
By making an application using MVC approach, you achieve many advantages, but I personally feel scalability and resuablity are the best benefits. When your application grows larger, you just can't go and start making changes in each and every file. Instead of that, you need to add new changes in same file and MVC structure will make sure that your code runs fine.
If you are creating an employee
directory so you need to show details about every employee
which will certainly be different based on individual employee
. In such a case, by using MVC, you can give a general structure to employee
object (called Model
) and a general structure to view for every employee
. After that, you can create any number of employee
s (each having a different detail) and each employee
's details can be displayed on UI using view.
Moreover, if some other application requires the same employee
object, please feel free to reuse it there. :)
Dummy App to Explain MVC in JavaScript
App Name: Task Checker
Major features:
- Add different tasks
- Delete completed tasks
HTML Structure
The HTML structure is very simple with two very important tags. First with id 'template
' and another one with id 'task-box
'. The template div
is a generate view that will be used for displaying all the tasks. The container div
is 'task-box
' div
. Inside this div
, all the views will be appended.
JS Structure
In JS file, we have created 1 model class, 1 collection class, 1 view class and 1 controller class. We have used 'this
' at multiple places, but I can't describe it for now, so please try to ignore it. I'm sure you can easily understand this example without a very good understanding of 'this
'.
var collection = new taskCollection();
var view = new taskView();
var controller = new taskController(collection,view);
controller.init();
-
Since model means data, our taskModel
will have two variables (data is stored in variable only). Variable 'task
' represents task name and 'removeFlag
' helps to identify whether this particular task should be deleted or not.
function taskModel(){
var task="";
var removeFlag=false;
this.setTask = function(taskName){
task = taskName;
}
this.getTask = function(){
return task;
}
this.setFlag = function(flag){
removeFlag = flag;
}
this.getFlag = function(){
return removeFlag;
}
}
In this model, besides having two properties called 'task
' and 'removeFlag
', we have created their getters and setters also.
-
There is one collection
also called taskCollection
. This function gives collection of tasks. Besides getter/setter, there are two other methods called addTask
and keepTask
. addTask
method adds more tasks in the collection. keepTask
sets the value of flag that helps in identifying whether this task should be kept or deleted.
function taskCollection(){
var tasks = [];
this.getTasks = function(){
return tasks;
}
this.setTasks = function(tempTasks){
tasks = tempTasks;
}
this.addTask = function(task){
tasks.push(task);
}
this.keepTask = function(taskVal,flag){
for(index in tasks){
if(taskVal==tasks[index].getTask()){
tasks[index].setFlag(flag);
break;
}
}
}
}
-
After that, there is another class called taskView
. This is a view for our app. Here, two methods are created, viz, showAllTasks
and showTask
. Here, the method showAllTasks
is very important. This method gets all the tasks from task collection created in the previous step. After receiving all the tasks, it displays all those tasks where flag
is set to false
and it finally updates task collection with all these tasks which are still active (Remember, Task
collection is a collection of models and each model has a property 'flag
').
There is another method called showTask
, this method just displays individual task, i.e., whichever model is passed to this method. But in case of showAlltasks
, all the tasks are displayed from collection and having property flag
set to false
.
Please note that showAllTasks
is called when any task is deleted and all other tasks are redisplayed whereas showTask
is called whenever any task is added.
function taskView(){
var template = $('.task','#template');
this.showAllTasks=function(taskAllCollection){
var tempCollectionTasks=[];
var taskCollection = taskAllCollection.getTasks();
var len = taskCollection.length;
$('#task-box').html("");
for(index=0;index<len;index++){
var task = taskCollection[index];
var template = $("#template");
if(!task.getFlag()){
template.find('.task').html(task.getTask());
$('#task-box').append(template.html());
tempCollectionTasks.push(task);
}
}
taskAllCollection.setTasks(tempCollectionTasks);
}
this.showTask = function(taskModel){
var template = $("#template");
template.find('.task').html(taskModel.getTask());
$('#task-box').append(template.html());
}
}
-
After that, there is one more class which is our controller. Controller uses both view and collection objects. Here, the method init
is created that binds event on add button. This method creates an object of model, sets task on this model, adds this model to collection and shows this model details using its view.
I think, once you see the code, the remaining code is self-explanatory.
function taskController(collection,view){
this.init= function(){
$('#add-btn').off('click').on('click',function(){
var taskVal = $('#task-name').val();
if(taskVal.trim()!=''){
$('#task-name').val('');
var model = new taskModel();
model.setTask(taskVal);
collection.addTask(model);
view.showTask(model);
}
else{
alert('Please enter some value!!');
return;
}
});
this.addEvent();
}
this.addEvent = function(){
$('#task-box').off('click').on('click','.close',function(ev){
if($(ev.currentTarget).is(':checked')) {
$(ev.currentTarget).parent().css('text-decoration','line-through');
var taskVal = $(ev.currentTarget).parent().find('.task').text();
collection.keepTask(taskVal,true);
}
else{
$(ev.currentTarget).parent().css('text-decoration','none');
var taskVal = $(ev.currentTarget).parent().find('.task').text();
collection.keepTask(taskVal,false)
}
});
$('#remove-btn').off('click').on('click',function(){
view.showAllTasks(collection);
});
}
}
-
Finally, you need to create these objects to make the application run fine.
History
- 2nd December, 2014: Initial version