javascript
javascript的MVC三层架构(案例之分页插件)
javascript的MVC三層架構(案例之分頁插件)
作者:田想兵 博客地址:http://www.cnblogs.com/tianxiangbing
最近很少寫博文,一是比較忙,二是沒啥心情,好,言歸正傳,今天的主題是MVC版的javascript結構,做程序的,可能對MVC會有較深刻的印象,就是Model-View-Control,中文的意思就是模型-視圖-控制器,這好像已經是一個很成熟的結構了,后來又有些在它基礎上的拓展,有興趣的可以擺渡一下。所以它基本上適應任何情況下的編程,今天我們就要用它來實現js版的一個分頁控件。
首先,我們先明確每一層是做什么的:
View也就是視圖層,在這里面我們會去初始化一些html元素;
Model模型層,我一直認為這一層存在的意義不大,因為通常我們new一個js對象的時候,都會初始化它的一些變量,很少會去單獨寫個方法去設置它,所以就把Model改成發送ajax請求了;
Control控制器,這里就是一些業務邏輯了,這里我們可以再分出一個事件層來;
Event事件層,處理html事件。
中途停了一天,接著寫,不知道為啥,最近一直都沒有辦法集中精力,可能是因為兒童節吧,今天還要加班, 可悲的碼農啊,題外話不說了,繼續碼字。
現在我們來分析下需求,分頁控件,無非就是對數據的一個分組顯示,所以它一定會有pagesize(每頁條數)和count(總條數) 這兩個屬性,當然也有人喜歡把所有數據返回過來給前端來分頁,不過分頁的目的之一,就是為了減輕數據量,一次批量返回也不是不行,具體情況具體分析吧!有了count和pagesize后,我們就可以算出總頁碼數了。
這個很簡單,就是整除有余的話就多一頁,否則取整數部分。
我們先看下效果圖,不然的話,腦子里沒有一個結構,也是無法下手的。請觀看下圖:
?
??
接著該MVC三層結構出場了,我們先在view(視圖層)初始化一些必要的HTML元素:
view:function(method,args){????????????????var?_self=this;????
????????var?_class={
????????????page:function(args){
????????????????var?_html='\
????????????????????????<div?class="pager">\
????????????????????????????<a?class="firstPage"?href="javascript:void(0);">首頁</a>\
????????????????????????????<a?class="prePage"?href="javascript:void(0);">上一頁</a>\
????????????????????????????<span?class="inputPage">第<input?type="text"?value="'+?_self.currentIndex?+'"?class="txt_curIndex"?name="txt_curIndex"/>頁/<i>'+_self.sumPage+'</i>頁</span>\
????????????????????????????<a?class="nextPage"?href="javascript:void(0);">下一頁</a>\
????????????????????????????<a?class="lastPage"?href="javascript:void(0);">末頁</a>\
????????????????????????</div>\
????????????????????????????';
????????????????_self.content.html(_html);
????????????????_self.event("bind",args);
????????????}
????????};
????????return?_class[method](args);
????}
?在這里,我又調用了事件層,來給這些HTML元素綁定相應的事件,這里大概有五個事件,就是上一頁,下一頁,首頁,未頁,及跳轉。這些事件,其本質就是改變頁碼數,好,那我們就寫個請求頁碼數的方法:
model:function(method,args){????????var?_self=this;
????????var?_class={
????????????go:function(args){
????????????????return?$.ajax({
????????????????????url:_self.ajaxUrl,
????????????????????dataType:"json",
????????????????????async:true,
????????????????????data:args[0],
????????????????????success:function(data){
????????????????????????args[1](data);
????????????????????????_self.cpu("change",data);
????????????????????},
????????????????????type:"GET",
????????????????????error:function(data){
???????????????????????? alert("json格式不正確")
????????????????????}
????????????????});
????????????}
????????};
????????return?_class[method](args);
????}
這是個ajax請求,放在model層下面,有兩個參數,一個是ajax需要傳的參數{page:1} args[0],另一個是外部的一個回調方法,用來格式化內容的,這個跟分頁控件沒有半毛錢關系,所以就當作回調。好,接著我們在控制器層里就調用這個方法就行了,剛才說到有五個事件,這樣就對應了五個控制器:
????????var?_self=this;
????????var?_class={
????????????change:function(data){
????????????????var?arr?=?data;
????????????????if?(data.count>0){
????????????????????_self.count=data.count;
????????????????????_self.sumPage=?parseInt(?_self.count?%?_self.pageSize?>0???_self.count?/?_self.pageSize+1?:?_self.count?/?_self.pageSize);
????????????????????_self.view("page");
????????????????}
????????????},????????????????
????????????jump:function(args){
????????????????var?input?=?parseInt($("[name='txt_curIndex']",_self.content).val());
????????????????if?(input>0?&&?input?<=?_self.sumPage){
????????????????????_self.currentIndex?=?input;
????????????????????_self.ajaxArgs.page?=?_self.currentIndex-1;
????????????????????_self.model("go",[_self.ajaxArgs,_self.returnFunc]);
????????????????}
????????????},
????????????prev:function(args){
????????????????if?(_self.currentIndex?>?1){
????????????????????_self.currentIndex--;
????????????????????$("[name='txt_curIndex']",_self.content).val(_self.currentIndex);
????????????????????_self.cpu("jump",args);
????????????????}
????????????},
????????????next:function(args){????????????????
????????????????if?(_self.currentIndex?<?_self.sumPage?-?1){
????????????????????_self.currentIndex++;
????????????????????$("[name='txt_curIndex']",_self.content).val(_self.currentIndex);
????????????????????_self.cpu("jump",args);
????????????????}
????????????},
????????????last:function(args){
????????????????_self.currentIndex?=?_self.sumPage;
????????????????$("[name='txt_curIndex']",_self.content).val(_self.currentIndex);
????????????????_self.cpu("jump",args);
????????????},
????????????first:function(args){
????????????????_self.currentIndex?=?1;
????????????????$("[name='txt_curIndex']",_self.content).val(_self.currentIndex);
????????????????_self.cpu("jump",args);
????????????}
????????};
????????return?_class[method](args);
????}
};
?數一數,是不是五個,我勒個去,作者數學不好,竟然是他妹的六個,竟然多了個change,好啦,把chage這個放model里去吧,他的作用就是計算一些變量的值。
最后事件層只需要調用Control控制層相對應的方法就行了:
event:function(method,args){????????var?_self=this;
????????var?pager?=?$("div.pager",_self.content);
????????var?_class={
????????????bind:function(args){
????????????????$("[name='txt_curIndex']",_self.content).keydown(function(e){
????????????????????if?(e.keyCode==13){
????????????????????????_self.cpu("jump",args);
????????????????????}
????????????????});
????????????????$(".prePage",_self.content).click(function(){
????????????????????_self.cpu("prev",args);
????????????????});????
????????????????$(".nextPage",_self.content).click(function(){
????????????????????_self.cpu("next",args);
????????????????});
????????????????$(".lastPage",_self.content).click(function(){
????????????????????_self.cpu("last",args);
????????????????});
????????????????$(".firstPage",_self.content).click(function(){
????????????????????_self.cpu("first",args);
????????????????});
????????????}
????????};
????????return?_class[method](args);
????},
這樣是不是就完了呢,你猜?沒錯,恭喜你,猜對了,還沒有結束,因為我們還沒有看到入口,一般情況我們都喜歡定義一個名為init的方法來初始化,這次的情況也很一般,所以定義init吧:
????????var?_self?=?this;
????????_self.currentIndex?=?ops.currentIndex;
????????_self.ajaxArgs?=?$.extend(?ops.ajaxArgs,{page:this.currentIndex-1});
????????_self.model("go",[_self.ajaxArgs,_self.returnFunc]);
????},
整個分頁插件的代碼如下:
????this.currentIndex?=?1;
????this.count?=?ops.count;
????this.pageSize?=?ops.pageSize||10;
????this.sumPage?=?1;
????this.content?=?ops.content;
????this.ajaxUrl?=?ops.url;
????this.returnFunc=ops.returnFunc||new?Function();
};
Pager.prototype={
????init:function(ops){
????????var?_self?=?this;
????????_self.currentIndex?=?ops.currentIndex;
????????_self.ajaxArgs?=?$.extend(?ops.ajaxArgs,{page:this.currentIndex-1});
????????_self.model("go",[_self.ajaxArgs,_self.returnFunc]);
????},
????view:function(method,args){????????
????????var?_self=this;????
????????var?_class={
????????????page:function(args){
????????????????var?_html='\
????????????????????????<div?class="pager">\
????????????????????????????<a?class="firstPage"?href="javascript:void(0);">首頁</a>\
????????????????????????????<a?class="prePage"?href="javascript:void(0);">上一頁</a>\
????????????????????????????<span?class="inputPage">第<input?type="text"?value="'+?_self.currentIndex?+'"?class="txt_curIndex"?name="txt_curIndex"/>頁/<i>'+_self.sumPage+'</i>頁</span>\
????????????????????????????<a?class="nextPage"?href="javascript:void(0);">下一頁</a>\
????????????????????????????<a?class="lastPage"?href="javascript:void(0);">末頁</a>\
????????????????????????</div>\
????????????????????????????';
????????????????_self.content.html(_html);
????????????????_self.event("bind",args);
????????????}
????????};
????????return?_class[method](args);
????},
????event:function(method,args){
????????var?_self=this;
????????var?pager?=?$("div.pager",_self.content);
????????var?_class={
????????????bind:function(args){
????????????????$("[name='txt_curIndex']",_self.content).keydown(function(e){
????????????????????if?(e.keyCode==13){
????????????????????????_self.cpu("jump",args);
????????????????????}
????????????????});
????????????????$(".prePage",_self.content).click(function(){
????????????????????_self.cpu("prev",args);
????????????????});????
????????????????$(".nextPage",_self.content).click(function(){
????????????????????_self.cpu("next",args);
????????????????});
????????????????$(".lastPage",_self.content).click(function(){
????????????????????_self.cpu("last",args);
????????????????});
????????????????$(".firstPage",_self.content).click(function(){
????????????????????_self.cpu("first",args);
????????????????});
????????????}
????????};
????????return?_class[method](args);
????},
????model:function(method,args){
????????var?_self=this;
????????var?_class={
????????????go:function(args){
????????????????return?$.ajax({
????????????????????url:_self.ajaxUrl,
????????????????????dataType:"json",
????????????????????async:true,
????????????????????data:args[0],
????????????????????success:function(data){
????????????????????????args[1](data);
????????????????????????_self.model("change",data);
????????????????????},
????????????????????type:"GET",
????????????????????error:function(data){
????????????????????console.dir(data)
?????????????????????????alert("json格式不正確")
????????????????????}
????????????????});
????????????},
????????????change:function(data){
????????????????var?arr?=?data;
????????????????if?(data.count>0){
????????????????????_self.count=data.count;
????????????????????_self.sumPage=?parseInt(?_self.count?%?_self.pageSize?>0???_self.count?/?_self.pageSize+1?:?_self.count?/?_self.pageSize);
????????????????????_self.view("page");
????????????????}
????????????}
????????};
????????return?_class[method](args);
????},
????cpu:function(method,args){
????????var?_self=this;
????????var?_class={????????????????
????????????jump:function(args){
????????????????var?input?=?parseInt($("[name='txt_curIndex']",_self.content).val());
????????????????if?(input>0?&&?input?<=?_self.sumPage){
????????????????????_self.currentIndex?=?input;
????????????????????_self.ajaxArgs.page?=?_self.currentIndex-1;
????????????????????_self.model("go",[_self.ajaxArgs,_self.returnFunc]);
????????????????}
????????????},
????????????prev:function(args){
????????????????if?(_self.currentIndex?>?1){
????????????????????_self.currentIndex--;
????????????????????$("[name='txt_curIndex']",_self.content).val(_self.currentIndex);
????????????????????_self.cpu("jump",args);
????????????????}
????????????},
????????????next:function(args){????????????????
????????????????if?(_self.currentIndex?<?_self.sumPage?-?1){
????????????????????_self.currentIndex++;
????????????????????$("[name='txt_curIndex']",_self.content).val(_self.currentIndex);
????????????????????_self.cpu("jump",args);
????????????????}
????????????},
????????????last:function(args){
????????????????_self.currentIndex?=?_self.sumPage;
????????????????$("[name='txt_curIndex']",_self.content).val(_self.currentIndex);
????????????????_self.cpu("jump",args);
????????????},
????????????first:function(args){
????????????????_self.currentIndex?=?1;
????????????????$("[name='txt_curIndex']",_self.content).val(_self.currentIndex);
????????????????_self.cpu("jump",args);
????????????}
????????};
????????return?_class[method](args);
????}
};
OK,最后我們回過頭來看下,這個結構的優劣點,優點了,就是更方便于擴展,可以無限制的往下加,層次分得較清明,劣點是,層次過深,效率會低一些,而且看著不爽,所以我給他定位為,管理系統業務邏輯較多時使用,一般的JS效果插件還是使用扁平結構的好。今天就寫到這吧,謝謝您的觀看,最后的臺詞是:如果你有任何的疑問都不要來問我,請反復閱讀本文。也可以加入我的QQ群與其他人討論,本文的DEMO會放在群共享里。我的群號有5678537,70210212,閉幕.
轉載于:https://www.cnblogs.com/tianxiangbing/archive/2012/06/02/js_mvc.html
總結
以上是生活随笔為你收集整理的javascript的MVC三层架构(案例之分页插件)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 博客开张第一篇
- 下一篇: 中小企业私有云解决方案浅谈