`

AJAX表格分页模板:探讨基于Prototype框架的javascript面向对象设计(中)

阅读更多
        在上一篇文章中,我们用静态页面的方式,设计出了分页模板的表现形式,接下来让我们利用javascript这个强大的操盘手来粘合其余的部分吧。

第一步,我们需要设计一个抽象的基类,来实现代码复用(js的OO,不就是为了这个么,还有就是方便管理代码而已)。
        首先,我们搞个命名空间来管理基类及其子类:
js 代码
  1. var Tbi = new Object();    //全局命名空间  
       
        为啥叫“Tbi”?就不要问了,项目组的名称而已,呵呵:)接下来考虑我们的模板基类,他有什么特征呢?
        1、需要持有一个到页面容器的引用,以便将自身加入页面流;
        2、需要保存用户设定的每页显示条目数;
        3、需要保存获取分页数据的服务器端地址(URL);
        这些成员可以通过构造器来初始化,除此之外,为了避免数据更新发生混乱(这个在异步非缓存的时候需要注意),还要有一个全局异步对象来获取数据,但不需要通过参数提供。
        定义了成员变量,模板对象还需要有可操作的方法:
        1、构造函数:initialize,这个方法在构建Prototype风格构建类,实例化对象的时候会自动调用。另外有一些技巧下面会提到;
        2、在数据获取过程中,显示等待信息的方法:_showMessage,这里只是简单显示一句话,可以按需替换成显示图片等;
        3、显示模板初始页面的show方法(其中有两个故意设计的事件入口,供今后扩展使用):
                A、调用beforeShow,默认为空方法,什么也不做,可按需设定;
                B、调用_display方法,显示模板初始页面:
                        a、调用2中的方法显示等待信息;
                        b、调用_catchContent方法异步获取服务器数据。此方法可由所有模板共用,因此放到基类中达到代码重用。可                        以看到, 我们为了细粒度的控制Prototype的ajax封装,使用了transport属性。
                        c、在成功返回服务器数据之后,addContent方法将把分页内容添加到容器中,分两步来做:
                                 (1) addPage方法作为回调函数添加模板主体——抽象方法,由子类实现。
                                 (2) addNavigation方法根据实际情况生成并添加分页导航——抽象方法,我将它在一个子类中实现然后演示
                                 混入(mixin),其实完全可以在基类中提供达到同样的代码复用效果。
js 代码
 
  1. /* 
  2.  * 模板基类 
  3.  */  
  4. Tbi.Template = Class.create();  
  5. Tbi.Template.prototype = {  
  6.     initialize: function(){  
  7.         this._init.apply(this,arguments);  
  8.     },  
  9.       
  10.     _init: function(wrap,items,catchUrl) {  
  11.         this.wrap = $(wrap);  
  12.         this.items = items;  
  13.         this.catchUrl = catchUrl;  
  14.         this.ajax = null;   //全局异步对象  
  15.     },  
  16.       
  17.     // 显示等待信息  
  18.     _showMessage: function(text){  
  19.         this.wrap.innerHTML =  text;  
  20.     },  
  21.       
  22.     // 显示模板默认页面  
  23.     show: function(){  
  24.         this.beforeShow(); //显示前事件处理入口  
  25.         this._display();     
  26.         this.afterShow(); //显示后时间处理入口  
  27.     },  
  28.       
  29.     // 显示前事件处理入口  
  30.     beforeShow: function(){},  
  31.       
  32.     _display: function(){  
  33.         this._showMessage("正在获取数据,请稍等……");  
  34.         this._catchContent();  
  35.     },  
  36.       
  37.     //取得默认页面内容,由两个模板公用  
  38.     _catchContent: function(){  
  39.         if(this.ajax){  
  40.             this.ajax.transport.abort();  
  41.         }  
  42.         this.ajax = new Ajax.Request(  
  43.             this.catchUrl,  
  44.             {  
  45.                 method: "get",  
  46.                 parameters: {"mode":this.mode,"items":this.items},  
  47.                 onComplete: this.addContent.bind(this)  
  48.             }  
  49.         );  
  50.     },  
  51.       
  52.     // 添加页面内容  
  53.     addContent: function(xmlhttp){  
  54.         this.addPage(xmlhttp);          //抽象方法,添加页面内容  
  55.         this.addNavigation();           //抽象方法,添加分页导航  
  56.     },  
  57.       
  58.     // 显示后事件处理入口          
  59.     afterShow: function(){}  
  60. }  

一些技巧:
        为了实现在子类中覆盖initialize构造函数,我们只需要将基类的成员初始化工作委托给_init方法即可,下面会看到他的作用。
        模仿事件处理机制,我们留下了两个事件入口beforeShow和afterShow,分别可以设置显示前事前和显示后事件。
        Prototype为Function对象扩展了一个bind方法和bindAsEventListener方法,可以很方便的将函数上下文(this)切换为别的对象,这里,我们切换为模板对象。
bind和bindAsEventListener的功用相似,但是有一点区别,用bind切换的方法,如果有自动传入的参数,比如事件对象event,那么这个参数将被自动传入函数参数列表的最后,而后者则是自动传入函数参数列表的最前面,这个技巧很常用。比如改写一下上面的代码,我给onComplete事件传入一个自定义参数tmyArg,使用两种不同的绑定方法(xmlhttp是Prototype自动传入回调函数的参数):
js 代码
  1. //用bind方法  
  2. this.addContent.bind(this,myArg)  
  3. //调用方式  
  4. this.addContent(myArg,xmlhttp)  
  5.   
  6.   
  7. //用bindAsEventListener方法  
  8. this.addContent.bindAsEventListener(this,myArg)  
  9. //调用方式  
  10. this.addContent(xmlhttp,myArg) 

第二步,实现静态模板类StaticTemplate。对于静态模板,其显示过程是这样的:向服务器发起一次异步请求,返回所有分页数据,服务器按照客户设定的每页显示数量来生成所有页,一次新传回客户端。每一页由一对tbody元素定义,然后通过css类名来讲所有的页面隐藏,最后由客户端js来控制显示页面,初始显示第一页。服务器返回的数据格式如下(只要结构一样就可以了,没有行、列数目的限制,这可以参看前一篇文章中的css设定了解,是可以随表格大小伸缩的),总条目数为6,分了两页:
xml 代码
 
  1. <table id='pages'>      
  2.     <caption>静态分页模板</caption>      
  3.     <thead>      
  4.         <tr>      
  5.             <th>标题一</th>      
  6.             <th>标题二</th>      
  7.             <th>标题三</th>      
  8.             <th>标题四</th>      
  9.             <th>标题五</th>      
  10.             <th>标题六</th>      
  11.         </tr>      
  12.     </thead>      
  13.     <tbody class='hidden'>      
  14.         <tr>      
  15.             <td>1</td>      
  16.             <td>1</td>      
  17.             <td>1</td>      
  18.             <td>1</td>      
  19.             <td>1</td>      
  20.             <td>1</td>      
  21.         </tr>      
  22.         <tr>      
  23.             <td>2</td>      
  24.             <td>2</td>      
  25.             <td>2</td>      
  26.             <td>2</td>      
  27.             <td>2</td>      
  28.             <td>2</td>      
  29.         </tr>      
  30.         <tr>      
  31.             <td>3</td>      
  32.             <td>3</td>      
  33.             <td>3</td>      
  34.             <td>3</td>      
  35.             <td>3</td>      
  36.             <td>3</td>      
  37.         </tr>      
  38.         <tr>      
  39.             <td>4</td>      
  40.             <td>4</td>      
  41.             <td>4</td>      
  42.             <td>4</td>      
  43.             <td>4</td>      
  44.             <td>4</td>      
  45.         </tr>      
  46.         </tbody>      
  47.           
  48.         <tbody class='hidden'>      
  49.         <tr>      
  50.             <td>5</td>      
  51.             <td>5</td>     
  52.             <td>5</td>      
  53.             <td>5</td>      
  54.             <td>5</td>      
  55.             <td>5</td>      
  56.         </tr>      
  57.         <tr>      
  58.             <td>6</td>      
  59.             <td>6</td>      
  60.             <td>6</td>      
  61.             <td>6</td>      
  62.             <td>6</td>      
  63.             <td>6</td>      
  64.         </tr>      
  65.     </tbody>      
  66. </table>   


        StaticTemplate类中,addPage方法统计table中tbody元素的个数来确定总页数,并附加到对象上。以供
addNavigation方法成分页导航信息:
js 代码
  1. this.pageTotal = this.wrap.getElementsByTagName("tbody").length;  

        在addNavigation方法中,又一次用到了前面提过的bindAsEventListener
技巧,并通过切换css类名来达到突出显示当前页码以及显示页面。

具体的
StaticTemplate代码实现如下:
js 代码
 
  1. /* 
  2.  * 静态模板,一次请求全部数据 
  3.  */  
  4. Tbi.StaticTemplate = Class.create();  
  5. Tbi.StaticTemplate.prototype = Object.extend(new Tbi.Template(),  
  6.     {  
  7.         /* 
  8.          * 构造函数,实例化静态模板 
  9.          * 参数:父容器,每页显示条目数,数据获取地址
  10.          */  
  11.         initialize: function(wrap,items,catchUrl){  
  12.             this._init(wrap,items,catchUrl);  
  13.             this.mode = "static";  
  14.         },  
  15.           
  16.         // 实现父类抽象方法,向页面添加默认分页  
  17.         addPage: function(xmlhttp){  
  18.             this.wrap.innerHTML = xmlhttp.responseText;  
  19.             this.pageTotal = this.wrap.getElementsByTagName("tbody").length;  
  20.             var table = $("pages");  
  21.             var pages = $A(table.getElementsByTagName("tbody"));  
  22.             displayPage = pages[0];  
  23.             displayPage.className = "";  
  24.         },  
  25.           
  26.         // 实现父类抽象方法,向页面添加分页导航  
  27.         addNavigation: function(){  
  28.             if(this.pageTotal>1){  
  29.                 var navigation = document.createElement("div");  
  30.                 navigation.id = "navigation";  
  31.                 var context = this;  
  32.                 $R(1,this.pageTotal,false).each(  
  33.                     function(item){  
  34.                         var link = document.createElement("a");  
  35.                         link.href = "#";  
  36.                         link.onclick = context._changePage.bindAsEventListener(context,link);  
  37.                         link.appendChild(document.createTextNode(item));  
  38.                         if(item==1){  
  39.                             link.className = "active";  
  40.                         }  
  41.                         navigation.appendChild(link);  
  42.                     }  
  43.                 );  
  44.                 this.wrap.appendChild(navigation);    
  45.             }             
  46.         },  
  47.           
  48.         // 导航链接点击事件处理函数,切换页面内容,同时改变导航链接样式(突出显示当前页)  
  49.         _changePage: function(event,link){  
  50.             var activeLink = $$('#TMPwrap div a[class="active"]')[0];  
  51.             if(activeLink != link){  
  52.                 var pages = $$("#TMPwrap tbody");  
  53.                 var oldPage = pages.find(  
  54.                     function(item){  
  55.                         return item.className == "";  
  56.                     }  
  57.                 );  
  58.                 var newPage = pages[link.firstChild.nodeValue-1]; //inner系列属性不兼容ff
  59.                 oldPage.className = "hidden";  
  60.                 newPage.className = "";  
  61.                 activeLink.className = "";  
  62.                 link.className = "active";  
  63.             }  
  64.             Event.stop(event);    
  65.         }  
  66.     }  
  67. );  

这样,我们就完成了静态分页模板的设计和实现,下一步是实现动态异步的两种获取方式模板。

接下来的内容,请参看:

AJAX表格分页模板:探讨基于Prototype框架的javascript面向对象设计(下)


分享到:
评论
9 楼 vito_fh 2007-06-12  
学习一下
8 楼 agile_boy 2007-05-29  
在OO的包装方面,我觉得mootools挺不错的
7 楼 笨笨狗 2007-05-29  
to jiangzhen1984:

之所以这么写,就是为了探讨Prototype风格的OO特性。其实如此包装的话,是可以提高可维护性的,增加命名空间,封装成类、对象。

dwr,个人对那种数据通信方式不是很感冒。相反,自己定义好数据传输格式,可以更灵活,比如支持REST架构。
6 楼 jiangzhen1984 2007-05-29  
我觉得你写的代码太复杂了,当然如果是为了功能强大,那就没什么好说的了  你的支持DWR吗?
我个人认为JS代码 越简单越好 因为JS代码可维护性太低了
5 楼 InnocentBoy 2007-05-18  
好东西,共欣赏。
4 楼 simohayha 2007-05-16  
呵呵,有bug可以给ouc jj报告呀。
3 楼 leondu 2007-05-16  
笨笨狗 写道
抱怨一句,je的代码编辑工具真的是太难用了啊,老是显示有问题,怎么回事?好影响心情,为了正确显示html代码,我都改了无数的次了,不知道是什么bug……


推荐帖子里面简要介绍下内容,具体代码作为附件上传,省时省力,呵呵。
2 楼 agile_boy 2007-05-16  
不错的学习示例
1 楼 笨笨狗 2007-05-16  
抱怨一句,je的代码编辑工具真的是太难用了啊,老是显示有问题,怎么回事?好影响心情,为了正确显示html代码,我都改了无数的次了,不知道是什么bug……

相关推荐

    AJAX表格分页模板:探讨基于Prototype框架的javascript面向对象设计

    火龙果软件工程技术中心 数据分页显示,是很普遍的需求,传统的实现大多是基于服务器端导航的,这种设计采用同步方式进行数据传输,用户体验很差。下面是我在学习ajax的过程中,实现的一个解决方案,不知道设计得...

    ajax分页模板示例

    本示例主要探讨的是一个基于HTML和Ajax实现的简单实用分页模板,它利用Prototype JavaScript框架实现面向对象的设计。 **一、Prototype框架介绍** Prototype是JavaScript的一个开源库,它扩展了JavaScript语言,...

    一个对html表格分页的类

    `prototype.js` 文件可能是引入了JavaScript的原型链扩展,这是一种常用的增强JavaScript对象和类的方式,使我们可以像面向对象编程语言一样进行开发。通过扩展JavaScript的原型,我们可以为原生对象添加新的属性和...

    ajax完成分页程序

    AJAX分页是指通过AJAX技术来实现页面数据的动态加载,用户在浏览过程中无需刷新整个页面即可查看不同页的数据。这种方式可以极大地提高网页的响应速度和用户体验。 #### 三、核心代码分析 首先,我们来看一下`...

    prototype笔记(9)----结合Prototype和JSON开发AJAX

    在本篇"prototype笔记(9)----结合Prototype和JSON开发AJAX"中,我们将深入探讨如何利用Prototype JavaScript库与JSON(JavaScript Object Notation)技术来高效地开发异步JavaScript应用程序,也就是我们常说的AJAX...

    简单易懂js分页(已封装)

    本文将深入探讨如何在JavaScript中实现简单易懂的分页功能。 首先,我们需要理解分页的基本概念。分页是将大量数据分成若干个较小的部分,每个部分称为一页,用户可以逐页浏览。在网页中,分页通常包括上一页、...

    用AJax框架做的小项目

    在本项目中,我们将探讨如何使用Ajax框架来实现一些基础的小项目,非常适合初学者进行学习和实践。 ### 1. Ajax 基础概念 - **异步通信**:Ajax的核心特性是异步通信,意味着用户可以继续浏览网页,而数据请求和...

    AJAX教程EXT教程JQUERY教程DWR教程PROTOTYPE教程

    在这些教程中,你将学习到如何使用AJAX实现页面的异步更新,使用EXTJS构建富客户端应用,利用jQuery进行高效的DOM操作和Ajax交互,通过DWR实现Java和JavaScript之间的无缝通信,以及如何利用Prototype库增强...

    jquery prototype dojo 之 Ajax example and 学习总结

    本文将结合标题“jquery prototype dojo 之 Ajax example 和学习总结”以及描述,深入探讨jQuery、Prototype和Dojo这三种JavaScript库中的Ajax应用,以及相关的学习要点。 首先,jQuery是目前最流行的JavaScript库...

    基于J2EE的Ajax宝典

    - **Dojo, Prototype, YUI**:其他一些JavaScript框架也提供了强大的Ajax支持,各有特色,可根据项目需求选择。 4. **异步数据处理** - **动态加载内容**:通过Ajax实现页面部分内容的动态加载,如分页、无限滚动...

    JS Ajax XML 处理 (prototype)

    在JavaScript库Prototype中,Ajax的使用大大简化了与服务器的异步交互过程。本篇文章将深入探讨如何在Prototype中处理XML数据,以及相关的源码分析。** **一、Prototype库中的Ajax基础** Prototype是一个流行的...

    《ajax入门经典》源代码

    7. **Ajax实战**:深入探讨Ajax在实际项目中的应用,如表单验证、实时数据刷新、无刷新分页等常见场景。 8. **Ajax与AJAX库**:介绍jQuery、Prototype等流行的Ajax库,简化Ajax开发过程。 9. **Ajax性能优化**:...

    基于Java的国产Ajax框架 Buffalo.zip

    **基于Java的国产Ajax框架 Buffalo** Ajax(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。它通过在后台与服务器进行少量数据交换,使网页实现异步更新,提升...

    ajax 分页技术很好用

    本文将深入探讨AJAX分页技术的实现原理及具体应用,并通过一个具体的示例来展示如何利用AJAX技术实现高效的分页功能。 #### 二、AJAX分页技术概述 AJAX分页技术是基于异步请求的一种分页方式,它可以在不刷新整个...

    ajax框架与struts框架的最佳结合讲解

    Ajax技术允许前端页面无刷新地与服务器进行交互,提升用户体验,而Struts框架则是一个基于MVC(Model-View-Controller)设计模式的Java Web应用框架,它简化了后台逻辑处理。将两者结合起来可以实现高效、流畅的用户...

    AJAX高级程序设计.rar

    2. **Prototype**:另一个早期的JavaScript框架,其AJAX功能也很强大。 3. **AngularJS**:一个由Google维护的MVC框架,内置了强大的AJAX服务,如$http。 4. **Vue.js和React.js**:现代前端框架,虽然不直接包含...

    Ajax与DWR课件

    1. **对象扩展**:Prototype提供了一种强大的方式来扩展JavaScript原生对象,比如Array、String等。 2. **DOM操作**:Prototype提供了一套友好的DOM操作接口,如Element对象,简化了对HTML元素的操作。 3. **Ajax...

    《基于J2EE的Ajax宝典》中的源代码

    在《基于J2EE的Ajax宝典》这本书中,作者深入探讨了如何利用Ajax技术增强J2EE应用的功能和性能。17章的源码尤其值得关注,因为这一章通常会涵盖一些关键概念和实践技巧,如: 1. **Ajax基础**:介绍Ajax的基本工作...

Global site tag (gtag.js) - Google Analytics