About the MVC pattern in JavaScript

Source: Internet
Author: User

Original article: Model-View-Controller (MVC) with JavaScript
Author: Alex @ Net
Translation: JavaScript MVC pattern
Translator: justjavac

This article introduces the implementation of Model-View-controller mode in JavaScript.

I like JavaScript because it is one of the most flexible languages in the world. In JavaScript, programmers can choose a programming style based on their own tastes: process-oriented or object-oriented. If you have a strong taste, JavaScript can be used as well: process-oriented, object-oriented, and Aspect-Oriented. JavaScript developers can even use functional programming technology.

In this article, my goal is to write a simple JavaScript component to show you how powerful JavaScript is. This component is an editable Project List (select tag in HTML). You can select an item and delete it, or add a new project to the list. The component is composed of three classes, which correspond to the Model-View-controller in the MVC design mode.

This article is just a simple guide. If you want to use it in the actual project, you need to make appropriate changes. I believe that you have everything you need to create and run JavaScript programs: brains, hands, text editors (such as NotePad), browsers (such as my favorite Chrome ).

Since our code uses the MVC pattern, I will briefly introduce this design pattern here. The English name of the MVC pattern is Model-View-Controller pattern. As the name suggests, it consists of the following parts:

• Model (), used to store the data used in the program;
• Views are presented in different forms;
• The Controller updates the model.
In Wikipedia's definition of the MVC Architecture, it consists of the following three parts:

Model-Model is used to encapsulate data related to the application's business logic and to process the data. The "model" has the right to directly access data. "Model" does not depend on "View" and "controller", that is, the model does not care about how it is displayed or operated.

View-the View layer can display data purposefully. It is usually a user interface element. Generally, there is no program logic in the view. In Web applications, MVC usually calls the html page that displays dynamic data as a view.

Controller-handles and responds to events, usually user operations, monitors changes in the model, and then modifies the view.

The data of the component is a list of items, in which one particle item can be selected and deleted. so, the model of the component is very simple-it is stored in an array property and selected item property; and here it is:

We will implement a data list component based on MVC, and projects in the list can be selected and deleted. Therefore, the component model is very simple-It only requires two attributes:

1. array _ items is used to store all elements
2. The common variable _ selectedIndex is used to store the selected element index.
The Code is as follows:

Copy codeThe Code is as follows:
/**
* Model.
*
* The model stores all elements and notifies the Observer (Observer) when the status changes ).
*/
Function ListModel (items ){
This. _ items = items; // all elements
This. _ selectedIndex =-1; // index of the selected Element

This. itemAdded = new Event (this );
This. itemRemoved = new Event (this );
This. selectedIndexChanged = new Event (this );
}

ListModel. prototype = {
GetItems: function (){
Return []. concat (this. _ items );
},

AddItem: function (item ){
This. _ items. push (item );
This. itemAdded. Policy ({item: item });
},

RemoveItemAt: function (index ){
Var item;

Item = this. _ items [index];
This. _ items. splice (index, 1 );
This. itemRemoved. Policy ({item: item });

If (index = this. _ selectedIndex ){
This. setSelectedIndex (-1 );
}
},

GetSelectedIndex: function (){
Return this. _ selectedIndex;
},

SetSelectedIndex: function (index ){
Var previusindex;

Previusindex = this. _ selectedIndex;
This. _ selectedIndex = index;
This. selectedIndexChanged. Policy ({previous: previusindex });
}
};

Event is a simple class that implements the Observer pattern:

Copy codeThe Code is as follows:
Function Event (sender ){
This. _ sender = sender;
This. _ listeners = [];
}

Event. prototype = {
Attach: function (listener ){
This. _ listeners. push (listener );
},

Y: function (args ){
Var index;

For (index = 0; index <this. _ listeners. length; index + = 1 ){
This. _ listeners [index] (this. _ sender, args );
}
}
};

The View class must define a controller class to interact with it. Although this task can have many different interfaces, I prefer the simplest one. I want my project to add a project in a ListBox control and two buttons Under it: the plus sign button, and the minus sign to delete the selected project. The "select" function provided by the component requires the support of the native function of the select control.

A View class is bound to a Controller class 「... The controller processes user input events, usually through a registered callback function (wikipedia.org ).

The following are the View and Controller classes:

Copy codeThe Code is as follows:
/**
* View.
*
* The View displays model data and triggers UI events.
* The controller is used to process these User Interaction Events.
*/
Function ListView (model, elements ){
This. _ model = model;
This. _ elements = elements;

This. listModified = new Event (this );
This. addButtonClicked = new Event (this );
This. delButtonClicked = new Event (this );

Var _ this = this;

// Bind the model listener
This. _ model. itemAdded. attach (function (){
_ This. rebuildList ();
});

This. _ model. itemRemoved. attach (function (){
_ This. rebuildList ();
});

// Bind the listener to the HTML Control
This. _ elements. list. change (function (e ){
_ This. listModified. Policy ({index: e.tar get. selectedIndex });
});

This. _ elements. addButton. click (function (){
_ This. addButtonClicked. Groovy ();
});

This. _ elements. delButton. click (function (){
_ This. delButtonClicked. Policy ();
});
}

ListView. prototype = {
Show: function (){
This. rebuildList ();
},

RebuildList: function (){
Var list, items, key;

List = this. _ elements. list;
List.html ('');

Items = this. _ model. getItems ();
For (key in items ){
If (items. hasOwnProperty (key )){
List. append ($ ('<option>' + items [key] + '</option> '));
}
}

This. _ model. setSelectedIndex (-1 );
}
};

/**
* Controller.
*
* The Controller responds to user operations and calls variable functions on the model.
*/
Function ListController (model, view ){
This. _ model = model;
This. _ view = view;

Var _ this = this;

This. _ view. listModified. attach (function (sender, args ){
_ This. updateSelected (args. index );
});

This. _ view. addButtonClicked. attach (function (){
_ This. addItem ();
});

This. _ view. delButtonClicked. attach (function (){
_ This. delItem ();
});
}

ListController. prototype = {
AddItem: function (){
Var item = window. prompt ('add item :','');
If (item ){
This. _ model. addItem (item );
}
},

DelItem: function (){
Var index;

Index = this. _ model. getSelectedIndex ();
If (index! =-1 ){
This. _ model. removeItemAt (this. _ model. getSelectedIndex ());
}
},

UpdateSelected: function (index ){
This. _ model. setSelectedIndex (index );
}
};

Of course, the Model, View, and Controller classes should be instantiated.

The following is a complete code using this MVC:

Copy codeThe Code is as follows:
$ (Function (){
Var model = new ListModel (['php', 'javascript ']),

View = new ListView (model ,{
'LIST': $ ('# list '),
'Addbutton': $ ('# plusBtn '),
'Delete': $ ('# minusBtn ')
}),

Controller = new ListController (model, view );
View. show ();
});

<Select id = "list" size = "10" style = "width: 15em"> </select> <br/>
<Button id = "plusBtn"> + </button>
<Button id = "minusBtn">-</button>

 

 

 

 


 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.