亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

超級簡單實現JavaScript MVC 樣式框架

2019-11-20 12:52:25
字體:
來源:轉載
供稿:網友

 介紹

  使用過JavaScript框架(如AngularJS, Backbone 或者Ember)的人都很熟悉在UI(用戶界面,前端)中mvc的工作機理。這些框架實現了MVC,使得在一個單頁面中實現根據需要變化視圖時更加輕松,而模型-視圖-控制器(mvc)的核心概念就是:處理傳入請求的控制器、顯示信息的視圖、表示業務規則和數據訪問的模型。

  因此,當需要創建這樣一個需要在單個頁面中實現切換出不同內容的應用時,我們通常選擇使用上述框架之一。但是,如果我們僅僅需要一個在一個url中實現視圖切換的框架,而不需要額外捆綁的功能的話,就不必使用象Angular和Ember等復雜的框架。本文就是嘗試使用簡單、有效方法來解決同樣的問題。

 概念

  應用中的代碼利用urls中的“#”實現MVC模式的導航。應用以一個缺省的url開始,基于哈希值的代碼加載應用視圖并且將對象-模型應用于視圖模板。

  url格式像下面這樣:

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

  視圖內容必須以{{Property-Name}}的方式綁定對象模型的值和屬性。代碼會查找這個專門的模板格式并且代替對象模型中的屬性值。

  以ajax的方式異步加載的視圖會被放置于頁面的占位符中。視圖占位符可以是任何的元素(理想的情況是div),但是它必須有一個專門的屬性,代碼根據這個專門的屬性來定位它,這樣同樣有助于代碼的實現。當url改變時,會重復這個場景,另外一個視圖被加載。聽起來很簡單吧!下面的流程圖解釋了在這個特定的實現中的消息跳轉。

 寫代碼

  我們以基本的模塊設計模式開始,并且最終用門面設計模式的方式將我們的libs曝光于全局范圍內。

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

  我們需要將視圖元素存儲到一個變量中,這樣就可以多次使用。

var_viewElement=null;//elementthatwillbeusedtorendertheview

  我們需要一個缺省的路由來應對url中沒有路由信息的情況,這樣就缺省的視圖就可以被加載而不是展示空白頁面。

var_defaultRoute=null;

  現在我們來創建我們的主要MVC對象的構造方法。我們會把路由信息存儲在“_routeMap”中

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

  是時候創建路由對象了,我們會將路由、模板、控制器的信息存儲在這個對象中。

var routeObj = function (c, r, t) {  this.controller = c;  this.route = r;  this.template = t;}

  每一個url會有一個專門的路由對象routeObj.所有的這些對象都會被添加到_routeMap對象中,這樣我們后續就可以通過key-value的方式獲取它們。

  為了添加路由信息到MVC libs中,我們需要曝光libs中的一個方法。所以讓我們創建一個方法,這個方法可以被各自的控制器用來添加新路由。

jsMvc.prototype.AddRoute = function (controller, route, template) {  this._routeMap[route] = new routeObj(controller, route, template);}

  方法AddRoute接收3個參數:控制器,路由和模板(contoller, route and template)。他們分別是:

  controller:控制器的作用就是訪問特定的路線。

  route:路由的路線。這個就是url中#后面的部分。

  template:這是外部的html文件,它作為這個路由的視圖被加載。現在我們的libs需要一個切入點來解析url,并且為相關聯的html模板頁面提供服務。為了完成這個,我們需要一個方法。

  Initialize方法做如下的事情:

  1)獲取視圖相關的元素的初始化。代碼需要一個具有view屬性的元素,這樣可以被用來在HTML頁面中查找:

  2)設置缺省的路由

  3)驗證視圖元素是否合理

  4)綁定窗口哈希變更事件,當url不同哈希值發生變更時視圖可以被及時更新

  5)最后,啟動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 = startMvcDelegate;  startMvcDelegate();}

  在上面的代碼中,我們從startMvc方法中創建了一個代理方法startMvcDelegate。當哈希值變化時,這個代理都會被調用。下面就是當哈希值變化時我們做的操作的先后順序:

  1)獲取哈希值

  2)從哈希中獲取路由值

  3)從路由map對象_routeMap中獲取路由對象routeObj

  4)如果url中沒有路由信息,需要獲取缺省的路由對象

  5)最后,調用跟這個路由有關的控制器并且為這個視圖元素的視圖提供服務

  上面的所有步驟都被下面的startMvc方法所實現

//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}

  下一步,我們需要使用XML HTTP請求異步加載合適的視圖。為此,我們會傳遞路由對象的值和視圖元素給方法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) {      loadView(routeObject, view, xmlhttp.responseText);    }  }  xmlhttp.open('GET', routeObject.template, true);  xmlhttp.send();}

  當前只剩加載視圖和將對象模型與視圖模板綁定了。我們會創建一個空的模型對象,然后傳遞與方法相關的模型來喚醒路由控制器。更新后的模型對象會與先前已經加載的XHR調用中的HTML模板綁定。

  loadView方法被用于調用控制器方法,以及準備模型對象。

  replaceToken方法被用于與HTML模板一起綁定模型

//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),       modelProps.forEach(function (element, index, array) {    viewHtml = viewHtml.replace('{{' + element + '}}', model[element]);  });  return viewHtml;}

  最后,我們將插件曝光于js全局范圍外

//attach the mvc object to the windoww['jsMvc'] = new jsMvc();

  現在,是時候在我們單頁應用中使用這個MVC插件。在下一個代碼段中,下面這些會實現:

  1)在web頁面中引入這個代碼

  2)用控制器添加路由信息和視圖模板信息

  3)創建控制器功能

  4)最后,初始化lib。

  除了上面我們需要的鏈接讓我們導航到不同的路徑外,一個容器元素的視圖屬性包含著視圖模板html。

<!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</h3>  <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</h3>  <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 = '555-123456';    }     function AdminController(model) {      model.UserName = "John";      model.Password = "MyPassword";    }  </script></body></html>

  上面的代碼有一段包含一個為IE的條件注釋。

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

  如果IE的版本低于9,那么function.bind,Object.getOwnPropertyNames和Array.forEach屬性將不會被支持。因此我們要通過判斷瀏覽器是否低于IE9來反饋代碼是否支持。

  其中的內容有home.html, contact.html 和 admin.html 請看下面:

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

  完整的代碼可以從給定的下載鏈接中得到。

 如何運行代碼

  運行該代碼比較簡單,需要在你喜歡的Web服務器上創建一個Web應用,下面以IIS為例來說明。

  首先在默認站點中新增一個Web應用.

  然后設置必填信息:別名,物理路徑,應用池,用戶認證信息,點擊OK。

  最后定位到Web應用的內容目錄,瀏覽你想打開的HTML頁面即可。

  跑在服務器里是必要的,因為代碼加載從存儲于外部文件中的視圖,瀏覽器不會允許我們的代碼在非宿主服務器環境下執行。當然如果你使用Visual Studio那么直接在目標html文件上右鍵,選擇‘View In Browser'即可。

 瀏覽器支持

  大部分的現代瀏覽器都支持本代碼。針對IE8及以下的瀏覽器,有一份單獨的代碼來支持,但很不幸,這份代碼遠多于100行。因此這代碼不是百分百跨瀏覽器兼容的,所以當你決定在項目中使用時需要對代碼進行微調。

 興趣點

  This example demonstrates這個示例向我們展示了對于非常明確地需求來說,真沒必要全部使用js庫和框架來實現。Web應用是資源密集型的,最好只使用必要的代碼而丟掉其他多余部分。

  目前的代碼能做的就這些了。沒有諸如Web服務調用,動態事件綁定功能的。很快我會提供支持更多特性的升級版本。

以上所述就是本文的全部內容了,希望能對大家熟練掌握javascript有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩一区二区在线| 亚洲免费一在线| 九九热这里只有在线精品视| 久久夜精品va视频免费观看| 日韩在线观看精品| 欧美老少做受xxxx高潮| 91精品国产沙发| 亚洲国产成人av在线| 国产视频精品一区二区三区| 日韩电影在线观看永久视频免费网站| 久久噜噜噜精品国产亚洲综合| 这里只有视频精品| 一区二区福利视频| 成人在线视频福利| 国产精品美乳在线观看| 国产精品日日做人人爱| 午夜美女久久久久爽久久| 亚洲在线观看视频网站| 久久亚洲精品一区二区| 国产日韩在线看片| 久久久久中文字幕| 精品五月天久久| zzjj国产精品一区二区| 成人做爰www免费看视频网站| 性金发美女69hd大尺寸| 色偷偷偷亚洲综合网另类| 亚洲欧洲国产一区| 国产午夜精品全部视频播放| 国产精品大片wwwwww| 欧洲美女7788成人免费视频| 亚洲最大成人免费视频| 色偷偷av一区二区三区乱| 亚洲男人天天操| 久久亚洲私人国产精品va| 欧美理论片在线观看| 2020久久国产精品| 国产亚洲aⅴaaaaaa毛片| 午夜精品蜜臀一区二区三区免费| 亚洲精品91美女久久久久久久| 国产精品人成电影在线观看| 国产成人综合久久| www.欧美三级电影.com| 欧美裸体xxxx极品少妇| 欧美高清在线播放| 亚洲精品第一国产综合精品| 日韩成人av在线| 国产精品网红福利| 精品中文视频在线| 亚洲国产精品资源| 国产日韩换脸av一区在线观看| 久久99精品国产99久久6尤物| 欧美性xxxxxxx| 色综合久久久888| 日韩亚洲在线观看| 正在播放欧美一区| 亚洲女人天堂视频| 久久频这里精品99香蕉| 欧美成人精品在线播放| 精品国产一区二区三区在线观看| 88国产精品欧美一区二区三区| 91在线视频九色| 色妞在线综合亚洲欧美| 国产欧美精品在线| 色婷婷久久av| 欧美亚洲第一区| 国产成人午夜视频网址| 精品久久久久久亚洲国产300| 国产精品精品久久久久久| 九九精品在线视频| 成人免费看黄网站| 久久99亚洲热视| 久久久久国色av免费观看性色| 92版电视剧仙鹤神针在线观看| 国产精品ⅴa在线观看h| 国产日产欧美精品| 国产美女高潮久久白浆| 国产精品美女www爽爽爽视频| 狠狠色狠狠色综合日日小说| 久久久精品视频在线观看| 国产激情久久久久| 亚洲精品一区二区三区婷婷月| 欧美主播福利视频| 国产亚洲激情在线| 欧美激情成人在线视频| 亚洲一区二区久久久久久| 久久天天躁夜夜躁狠狠躁2022| 成人福利免费观看| 国产精品极品尤物在线观看| 欧美成人免费全部观看天天性色| 2020国产精品视频| 丰满岳妇乱一区二区三区| 日韩中文字幕免费| 97视频在线观看亚洲| 国产丝袜一区二区三区免费视频| 在线亚洲男人天堂| 亚洲国产精品资源| 欧美黑人视频一区| 丁香五六月婷婷久久激情| 热久久美女精品天天吊色| 亚洲精品国产美女| 日本欧美爱爱爱| 成人黄色在线免费| www.99久久热国产日韩欧美.com| 亚洲美女av黄| 91精品国产91久久久久久吃药| 日韩电影大全免费观看2023年上| 日韩中文字幕久久| 激情成人在线视频| 欧美福利视频在线观看| 在线播放国产一区中文字幕剧情欧美| 亚洲天堂视频在线观看| 日韩小视频网址| 国产一区二区香蕉| 中文字幕精品www乱入免费视频| 日韩成人在线网站| 国产极品精品在线观看| 日韩av电影在线播放| 国产精品揄拍500视频| 欧美黄色片免费观看| 亚洲精品美女久久久久| 精品自拍视频在线观看| 亚洲一区www| 最近2019年好看中文字幕视频| 欧美激情一区二区三级高清视频| 亚洲国产精品va在线| 欧美日韩免费看| 日韩在线视频观看| 中文字幕精品久久久久| 欧美三级欧美成人高清www| 亚洲国产精品网站| 亚洲免费视频观看| 久久久久999| 亚洲一区亚洲二区亚洲三区| 秋霞成人午夜鲁丝一区二区三区| 青青青国产精品一区二区| 91日韩在线视频| 成人激情视频小说免费下载| 久久精品视频中文字幕| 亚洲黄色www网站| 国产精品偷伦视频免费观看国产| 亚洲欧美国产精品专区久久| 日韩免费观看av| 亚洲精品中文字幕女同| 久久久久久久久国产精品| 国产精品热视频| 日韩在线中文字幕| 欧美高清不卡在线| 国产精品久久久久久婷婷天堂| 色综合久久久久久中文网| 久久中文字幕国产| 国产欧美精品日韩| 亚洲xxxx18| 久久久久久国产免费| 亚洲区中文字幕| 久久久爽爽爽美女图片| 日韩免费在线电影| 欧美性高潮在线| 亚洲国产女人aaa毛片在线| 午夜精品视频网站| 波霸ol色综合久久| 美女黄色丝袜一区| 中日韩午夜理伦电影免费| 成人xxxxx| 最近的2019中文字幕免费一页|