JavaScript MVC style framework with 100 lines of code implementation

Source: Internet
Author: User

Introduced

People who have used JavaScript frameworks (such as AngularJS, Backbone, or ember) are familiar with how MVC works in the UI (user interface, front end). These frameworks implement MVC, making it easier to change views as needed in a single page, while the core concept of model-view-Controller (MVC) is the controller that processes incoming requests, the view that displays information, the model that represents business rules, and data access.

Therefore, we typically choose to use one of these frameworks when you need to create an app that needs to switch out different content in a single page. However, if we just need a framework that implements view switching in one URL, without the need for additional bundled functionality, it is not necessary to use complex frameworks such as angular and ember. This article attempts to use simple, effective methods to solve the same problem.

Concept

The code in the app implements the MVC pattern navigation using the "#" in URLs. The app starts with a default URL, and the hash-based code loads the app view and applies the object-model to the view template.

The URL format looks like this:

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

The view content must be bound to the value and properties of the object model in the same way as {{Property-name}}. The code looks for this specialized template format and replaces the attribute values in the object model.

Views that are loaded asynchronously in an Ajax manner are placed in a placeholder on the page. The view placeholder can be any element (ideally a div), but it must have a special attribute that the code locates on the basis of that particular attribute, which also helps with the implementation of the Code. When the URL changes, the scene is repeated, and another view is loaded. It sounds simple! The following flowchart explains the message jumps in this particular implementation.

Write code

We started with a basic module design pattern and finally exposed our libs to the global scope in the form of a façade design pattern.

; (Function (w, d, undefined) {//rest of the Code}) (window, document);

We need to store the view elements in a variable so that we can use them multiple times.

var _viewelement = null; element that would be a used to render the view

We need a default route to address the absence of routing information in the URL so that the default view can be loaded instead of showing blank pages.

var _defaultroute = null;

Now let's create a construction method for our main MVC object. We're going to store the routing information in "_routemap".

var jsmvc = function () {//mapping object for the routes this._routemap = {};}

It's time to create the routing object, and we'll store the information for the route, template, and controller in this object.

var routeobj = function (c, r, t) {this.controller = C;    This.route = R; This.template = t;}

Each URL will have a dedicated routing object routeobj. All of these objects are added to the _routemap object, so that we can get them by key-value in a subsequent way.

In order to add the route information to the MVC Libs, we need to expose a method in libs. So let's create a method that can be used by the respective controller to add a new route.

JsMvc.prototype.AddRoute = function (Controller, route, template) {This._routemap[route] = new Routeobj (Controller, RO Ute, template);}

Method Addroute receives 3 parameters: controllers, routes and templates (Contoller, route and template). They were:

Controller: The function of a control is to access a particular route.

Route: Routes for routes. This is the part of the URL that follows #.

Template: This is an external HTML file that is loaded as a view of this route. Now our Libs needs a pointcut to parse the URL and provide services for the associated HTML template page. In order to accomplish this, we need a method.

The Initialize method does the following things:

1) Gets the initialization of the view-related element. The code needs an element with a view attribute, which can be used to find it in an HTML page:

2) Set the default route

3) Verify that the view elements are reasonable

4) Bind window hash Change event, the view can be updated in time when different hash value of URL is changed

5) Finally, start MVC

initialize the mvc manager object to start  functioningjsmvc.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  =&nbSp;startmvcdelegate;    startmvcdelegate ();} 

In the above code, we created a proxy method startmvcdelegate from the Startmvc method. This proxy is called when the hash value changes. Here is the order of operations we do when the hash value changes:

1) Get the hash value

2) Get the route value from the hash

3) Get the routing object from the route map object _routemap routeobj

4) If there is no routing information in the URL, you need to get the default routing object

5) Finally, the controller that is associated with this route is called and serves the view of this view element

All of the above steps are implemented by the following Startmvc method

FUNCTION TO START THE MVC SUPPORTFUNCTION 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 load the appropriate view asynchronously using an XML HTTP request. To do this, we pass the value of the route object and the view element to the method loadtemplate.

Function to load external html datafunction 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)  {  &Nbsp;         loadview (routeobject, view,  Xmlhttp.responsetext);        }    }     xmlhttp.open (' Get', routeobject.template, true);     xmlhttp.send ();}

Currently, only the view is loaded and the object model is bound to the view template. We will create an empty model object and then pass the method-related model to wake the routing controller. The updated model object is bound to the HTML template in the XHR call that was previously loaded.

The Loadview method is used to invoke the Controller method and prepare the model object.

The Replacetoken method is used to bind the model together with an HTML template

Function to load the view with the templatefunction 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),         &nBsp;   modelprops.foreach (function  (Element, index, array)  {         viewhtml = viewhtml.replace ('{ {' + element + '}} ', model[element]);     });     return viewhtml;}

Finally, we expose the plugin outside of the JS global scope

Attach the MVC object to the Windoww['jsmvc'] = new Jsmvc ();

Now it's time to use this MVC plugin in our single page application. In the next code snippet, the following will be implemented:

1) Introduce this code in the Web page

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

3) Create Controller function

4) Finally, initialize Lib.

In addition to the links we need above to navigate to different paths, the view property of a container element contains the view template HTML.

<! doctype html>

The above code has a section that contains a conditional comment for ie.

<!--[if Lt IE 9]> <script src= "Jsmvc-ie8.js" ></script> <! [endif]-->

If the version of IE is less than 9, then the Function.bind,object.getownpropertynames and Array.foreach properties will not be supported. So we're going to tell whether the browser is supported by judging whether it's below IE9.

The contents of which are home.html, contact.html and admin.html see below:

Home.html:

{{Message}}

Contact.html:

{{FirstName}} {{lastname}}<br/>{{phone}}

Admin.html:

<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= "{{PASSW ORD}} "/></div>

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

How to Run code

Running this code is simple, you need to create a Web app on your favorite Web server, which is illustrated in IIS as an example.

First add a new Web app to the default site.

Then set the required information: alias, physical path, application pool, user authentication information, click OK.

Finally, navigate to the Web app's content directory and browse to the HTML page you want to open.

Running on the server is necessary because the code is loaded from a view stored in an external file, and the browser will not allow our code to execute in a non-hosted server environment. Of course if you use Visual Studio then right-click on the target HTML file and select ' View in Browser '.

Browser support

This code is supported by most modern browsers. For browsers with IE8 and below, there is a separate code to support, but unfortunately, this code is far more than 100 lines. So this code is not a cross-browser compatible, so you need to fine-tune your code when you decide to use it in your project.

Points of interest

This example of this example demonstrates shows that there is really no need to use the JS libraries and frameworks for very specific requirements. Web apps are resource-intensive, and it's best to use only the necessary code to throw away any extra parts.

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

    • Download javascript-mvc.zip-4.6 KB

    • JavaScript MVC on Github

    • Live Demo

Original address: Http://www.codeproject.com/Articles/869488/JavaScript-MVC-Style-Framework-in-Less-Than-Lines

100 Line code implementation of JavaScript MVC style framework

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.