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 codeRunning 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 supportThis 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 interestThis 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.
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