Simple JavaScript MVC style framework

Source: Internet
Author: User

Simple JavaScript MVC style framework

This article will share with you how to implement the javascript MVC style framework simply and effectively written by foreign friends. I hope you will like it.

 

 

Introduction

People who have used JavaScript frameworks (such as AngularJS, Backbone, or Ember) are familiar with the working mechanism of mvc in the UI (user interface, front-end. These frameworks implement MVC, making it easier to change the view as needed on a single page. The core concept of Model-View-controller (mvc) is: the controller that processes incoming requests, the view of displayed information, and the model that represents business rules and data access.

Therefore, when you need to create an application that requires switching between different content on a single page, we usually choose to use one of the above frameworks. However, if we only need a framework to implement view switching in a url without additional bundling functions, we do not need to use complicated frameworks such as Angular and Ember. This article tries to use simple and effective methods to solve the same problem.

Concept

The code in the application uses "#" in urls to implement the MVC mode navigation. The application starts with a default url, loads the application view based on the hash value code, and applies the object-model to the view template.

The url format is as follows:

Http: // Domain Name/index.html #/Route Name

The View content must be bound to the value and attribute of the object model in the form of {Property-Name. The code looks for this special template format and replaces the attribute values in the object model.

A view asynchronously loaded in ajax mode is placed in a placeholder of the page. A view placeholder can be any element (ideally div), but it must have a special attribute that the Code locates based on, this also facilitates code implementation. When the url changes, this scenario is repeated and another view is loaded. It sounds simple! The following flowchart explains the message redirection in this specific implementation.

Write code

We started with the basic module design model, and finally exposed our libs to the global scope using the facade design model.

;(function(w,d,undefined){//restofthecode})(window,document);

We need to store the view element in a variable so that it can be used multiple times.

var_viewElement=null;//elementthatwillbeusedtorendertheview

We need a default route to cope with the absence of routing information in the url, so that the default view can be loaded instead of displaying blank pages.

var_defaultRoute=null;

Now let's create the construction method of our main MVC object. We will store the route information in "_ routeMap ".

?

1

2

3

4

Var jsMvc = function (){

// Mapping object for the routes

This. _ routeMap = {};

}

It is time to create a route object. We will store the routing, template, and controller information in this object.

?

1

2

3

4

5

Var routeObj = function (c, r, t ){

This. controller = c;

This. route = r;

This. template = t;

}

Each url has a special route object routeObj. All these objects will be added to the _ routeMap object, so that we can get them through key-value later.

To add route information to MVC libs, We need to expose a method in libs. So let's create a method, which can be used by the respective controllers to add new routes.

?

1

2

3

JsMvc. prototype. AddRoute = function (controller, route, template ){

This. _ routeMap [route] = new routeObj (controller, route, template );

}

Method AddRoute receives three parameters: controller, route, and template ). They are:

Controller: the controller is used to access a specific route.

Route: route. This is the part after # in the url.

Template: This is an external html file. It is loaded as the routing view. Now our libs needs an entry point to parse the url and provide services for the associated html template page. To accomplish this, we need a method.

The Initialize method does the following:

1) Get the initialization of view-related elements. The Code requires an element with the view attribute, which can be used to search the HTML page:

2) set the default route

3) Verify that the view elements are reasonable

4) bind a window hash change event. When different hash values of the url change, the view chart can be updated in a timely manner.

5) Finally, start mvc

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

// Initialize the Mvc manager object to start functioning

JsMvc. prototype. Initialize = function (){

Var startMvcDelegate = startMvc. bind (this );

 

// Get the html element that will be used to render the view

_ ViewElement = d. querySelector ('[view]');

If (! _ ViewElement) return; // do nothing if view element is not found

 

// Set the default route

_ DefaultRoute = this. _ routeMap [Object. getOwnPropertyNames (this. _ routeMap) [0];

 

// Start the Mvc manager

W. onhashchange = startMvcDelegate;

StartMvcDelegate ();

}

In the above Code, we created a proxy method startMvcDelegate from the startMvc method. When the hash value changes, this proxy will be called. The following is the sequence of operations when the hash value changes:

1) obtain the hash value

2) obtain the route value from the hash

3) obtain the routeObj from the route map object routeMap.

4) if there is no route information in the url, You need to obtain the default route object.

5) Finally, call the Controller related to the route and provide services for the view element.

All the steps above are implemented by the startMvc method below.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

// Function to start the mvc support

Function startMvc (){

Var pageHash = w. location. hash. replace ('#',''),

RouteName = null,

RouteObj = null;

 

RouteName = pageHash. replace ('/', ''); // get the name of the route from the hash

RouteObj = this. _ routeMap [routeName]; // get the route object

 

// Set to default route object if no route found

If (! RouteObj)

RouteObj = _ defaultRoute;

 

LoadTemplate (routeObj, _ viewElement, pageHash); // fetch and set the view of the route

}

Next, we need to use the xml http request to asynchronously load the appropriate view. Therefore, we will pass the value and view element of the route object to the method loadTemplate.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

// Function to load external html data

Function loadTemplate (routeObject, view ){

Var xmlhttp;

If (window. XMLHttpRequest ){

// Code for IE7 +, Firefox, Chrome, Opera, Safari

Xmlhttp = new XMLHttpRequest ();

}

Else {

// Code for IE6, IE5

Xmlhttp = new ActiveXObject ('Microsoft. xmlhttp ');

}

Xmlhttp. onreadystatechange = function (){

If (xmlhttp. readyState = 4 & xmlhttp. status = 200 ){

LoadView (routeObject, view, xmlhttp. responseText );

}

}

Xmlhttp. open ('get', routeObject. template, true );

Xmlhttp. send ();

}

Currently, only views are loaded and the object model is bound to the view template. We will create an empty model object and pass the model related to the method to wake up the route controller. The updated model object is bound to the HTML template in the previously loaded XHR call.

The loadView method is used to call the Controller method and prepare model objects.

The replaceToken method is used to bind a model with an HTML template.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

// Function to load the view with the template

Function loadView (routeObject, viewElement, viewHtml ){

Var model = {};

 

// Get the resultant model from the controller of the current route

RouteObject. controller (model );

 

// Bind the model with the view

ViewHtml = replaceToken (viewHtml, model );

 

// Load the view into the view element

ViewElement. innerHTML = viewHtml;

}

 

Function replaceToken (viewHtml, model ){

Var modelProps = Object. getOwnPropertyNames (model ),

 

ModelProps. forEach (function (element, index, array ){

ViewHtml = viewHtml. replace ('{{' + element +' }}', model [element]);

});

Return viewHtml;

}

Finally, we expose the plug-in outside the global scope of js.

?

1

2

// Attach the mvc object to the window

W ['jsmvc '] = new jsMvc ();

Now, it is time to use this MVC plug-in our single-page application. In the next code segment, the following functions are implemented:

1) introduce this code to the web page

2) Add routing information and view template information with the Controller

3) create a controller

4) initialize lib.

In addition to the link we need above, we can navigate to different paths. The view attribute of a container element contains the view template html.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

<! DOCTYPE html>

<Html>

<Head>

<Title> JavaScript Mvc </title>

<Script src = "jsMvc. js"> </script>

<! -- [If lt IE 9]> <script src = "jsMvc-ie8.js"> </script> <! [Endif] -->

 

<Style type = "text/css">

. NavLinkContainer {

Padding: 5px;

Background-color: lightyellow;

}

 

. NavLink {

Background-color: black;

Color: white;

Font-weight: 800;

Text-decoration: none;

Padding: 5px;

Border-radius: 4px;

}

. NavLink: hover {

Background-color: gray;

}

</Style>

</Head>

<Body>

<H3> Navigation Links

<Div class = "NavLinkContainer">

<A class = "NavLink" href = "index.html #/home"> Home </a>

 

<A class = "NavLink" href = "index.html #/contact"> Contact </a>

 

<A class = "NavLink" href = "index.html #/admin"> Admin </a>

 

</Div>

<Br/>

<Br/>

<H3> View

<Div view> </div>

<Script>

JsMvc. AddRoute (HomeController, 'home', 'Views/home.html ');

JsMvc. AddRoute (ContactController, 'Contact ', 'Views/contact.html ');

JsMvc. AddRoute (AdminController, 'admin', 'Views/admin.html ');

JsMvc. Initialize ();

 

Function HomeController (model ){

Model. Message = 'Hello world ';

}

 

Function ContactController (model ){

Model. FirstName = "John ";

Model. LastName = "Doe ";

Model. Phone = '2014-555 ';

}

 

Function AdminController (model ){

Model. UserName = "John ";

Model. Password = "MyPassword ";

}

</Script>

</Body>

</Html>

The above code contains a condition comment for IE.

?

1

<! -- [If lt IE 9]> <script src = "jsMvc-ie8.js"> </script> <! [Endif] -->

If the IE version is earlier than 9, the function. bind, Object. getOwnPropertyNames and Array. forEach attributes are not supported. Therefore, we need to judge whether the browser is lower than IE9 to check whether the code is supported.

The content includes home.html, contact.html, and admin.html. See the following:

Home.html:

{{Message}}

Contact.html:

?

1

2

3

{FirstName }{{ LastName }}

<Br/>

{Phone }}

Admin.html:

?

1

2

3

4

5

6

7

8

<Div style = "padding: 2px; margin: 2px; text-align: left;">

<Label for = "txtUserName"> User Name </label>

<Input type = "text" id = "txtUserName" value = "{UserName}"/>

</Div>

<Div style = "padding: 2px; margin: 2px; text-align: left;">

<Label for = "txtPassword"> Password </label>

<Input type = "password" id = "txtPassword" value = "{Password}"/>

</Div>

The complete code can be obtained from the given download link.

How to run code

Running this code is relatively simple. You need to create a Web application on your favorite Web server. The following describes how to use IIS as an example.

First, add a new Web application to the default site.

Set the required information: alias, physical path, application pool, user authentication information, and click OK.

Finally, go to the Web application content directory and browse the HTML page you want to open.

It is necessary to run the code on the server. Because the code is loaded from the view stored in an external file, the browser will not allow our code to be executed in a non-host server environment. If you use Visual Studio, right-click the target html file and select 'view In Browser.

Browser support

Most modern browsers support this code. For IE 8 and earlier browsers, there is a separate code to support, but unfortunately, this code is far more than 100 lines. Therefore, this code is not fully cross-browser compatible, so you need to fine-tune the code when deciding to use it in the project.

Point of interest

This example demonstrates example shows that for a very clear requirement, it is really unnecessary to use all js libraries and frameworks for implementation. Web applications are resource-intensive. It is best to use only the necessary code and discard other unnecessary parts.

This is what the current code can do. There is no function such as Web service calling and dynamic event binding. Soon I will provide an upgraded version that supports more features.

  • Download JavaScript-Mvc.zip-4.6 KB

  • JavaScript Mvc on Github

  • Live Demo

    Address: http://www.codeproject.com/Articles/869488/JavaScript-MVC-Style-Framework-in-Less-Than-Lines

The above is all the content of this article, hoping to help you master javascript.

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.