飞嗨,欢迎您的光临,本博所发布之文章皆为作者亲测通过,如有错误,欢迎通过各种方式指正。(本博已于2015.12.6升级到php7,运行环境php7 php-fpm + nginx1.8.0)

node.js分页类

Node.js/JS lf 2158℃ 0评论

为了更好的掌握nodej.js,于是最近用node.js写了个小demo,发现node.js的库相对php还是少了许多。对于常用的分页类也没找到,于是就基于bootstrap自己写了一个。

      不过,不得不吐槽一下,node.js的异步也很坑,,,在对数据库select的时候是异步的,所有依赖数据库返回的逻辑都要写在回调函数里面,阔是,如果有多个逻辑需要数据库层层返回,无限的层层嵌入,,,oh,god!还好,分页类嵌套两层就阔以了。当然,借助库,这些异步操作也可以改成同步进行。可见,异步虽然流弊闪闪也有它的缺点,当然咯,go语言的协程可以解决异步操作,但是代码表现形式依然是同步的,我大php在5.5版本中也加入了对协程的支持。

    地址:https://github.com/liufee/nodejs

    分页效果:

nodejs page list

nodejs page list


nodejs page list

nodejs page list

/*
* @author liufee <job@feehi.com>
* @link http://blog.feehi.com
* @description nodejs分页类
**/
var url = require('url');

module.exports = function(req, total, params){

 this.total = total;//总记录数
 this.perPage = 20;//每页显示多少条记录
 this.pageListNum = 15;//分页按钮数量
 this.pageSign = 'page';//分页标识符
 this.totalPage = Math.ceil(this.total/this.perPage);
 this.req = req;//request对象
 this.config = {
 "header" : '<span style="position:relative;top:8px;left:10px" class="rows">第%CURRENT%/%TOTAL%页</span>',
 'first'  : '<li><a href="%HREF%" aria-label="fisrt"><span aria-hidden="true">首页</span></a></li>',
 'prev'   : '<li><a href="%HREF%" aria-label="Previous"><span aria-hidden="true">上一页</span></a></li>',
 'next'   : '<li><a href="%HREF%" aria-label="Next"><span aria-hidden="true">下一页</span></a></li>',
 'last'   : '<li><a href="%HREF%" aria-label="last"><span aria-hidden="true">尾页</span></a></li>',
 'list'	 : '<li class="%STATUS%"><a href="%HREF%">%NUM%</a></li>',//要输出的分页列表模版
 'theme'  : '<nav><ul class="pagination">%FIRST% %PREV% %PAGES% %NEXT% %LAST% %HEADER%</ul></nav>'
 };

 for(var key in params){
 if(key == 'pageListNum') this.pageListNum = params[key];
 if(key == 'pageSign') this.pageSign = params[key];
 if(key == 'perPage') this.perPage = params[key];
 if(key == 'config') this.config = params[key];
 }
 this.parseUrl = function(){
 var query = '';
 var urls = url.parse(this.req.url, true);
 var query = this.req._parsedOriginalUrl.pathname+'?';
 this.page = 1;
 for(var index in urls.query){
 if( index != this.pageSign ){
 query += index+'='+urls.query[index]+'&';
 }else{
 this.page = urls.query[index];
 }
 }
 this.query = query+this.pageSign+'=';
 }
 this.parseUrl();

 /*获取sql语句中limit部分*/
 this.getLimit = function(){
 if(this.page&&this.page>0){
 var start = (this.page-1) * this.perPage;
 }else{
 page = 1;
 var start = 1;
 }
 return "limit "+start+','+this.perPage;
 }

 this.getHeader = function(){
 return this.config.header.replace(/%CURRENT%/, this.page).replace(/%TOTAL%/, this.totalPage);
 }

 this.getFirst = function(){
 var first = '';
 if(this.page != 1){
 first = this.config.first.replace(/%HREF%/, this.query+1);
 }
 return first;
 }

 this.getPrev = function(){
 var prev = '';
 if(this.page != 1){
 var i = parseInt(this.page)-1;
 prev = this.config.prev.replace(/%HREF%/, this.query+i);
 }
 return prev;
 }

 this.getNext = function(){
 var next = '';
 if(this.page<this.totalPage){
 var i = parseInt(this.page)+1;
 next = this.config.next.replace(/%HREF%/, this.query+i);
 }
 return next;
 }

 this.getLast = function(){
 var last = '';
 if(this.page < this.totalPage){
 last = this.config.last.replace(/%HREF%/, this.query+this.totalPage);
 }
 return last;
 }

 this.getPages = function(){
 var nums = Math.ceil(this.pageListNum/2);
 var pages = '';
 var temp = '';
 if(this.page<=nums){//当前页不足显示分页数木的一半,从1-pageListNum
 for(var i=1; i<=this.pageListNum; i++){
 var status = 'disable';
 if(i == this.page){
 status = 'active';
 }
 temp = this.config.list.replace(/%STATUS%/, status).replace(/%HREF%/, this.query+i).replace(/%NUM%/, i);
 pages += temp;
 }
 }else{//从当前页,向前一半,向后一半
 for(var j=nums; j>1; j--){//前半部分li
 i = this.page-j+1;
 temp = this.config.list.replace(/%STATUS%/, 'disable').replace(/%HREF%/, this.query+i).replace(/%NUM%/, i);
 pages += temp;
 }
 pages += this.config.list.replace(/%STATUS%/, 'active').replace(/%HREF%/, this.query+this.page).replace(/%NUM%/, this.page);
 for(var j=1;j<nums;j++){//后半部分li
 i = parseInt(this.page)+j;
 if(i>this.totalPage) break;
 temp = this.config.list.replace(/%STATUS%/, 'disable').replace(/%HREF%/, this.query+i).replace(/%NUM%/, i);
 pages += temp;
 }
 }
 return pages;
 }

 this.showPage = function(){
 var header = this.getHeader();
 var first = this.getFirst();
 var prev = this.getPrev();
 var next = this.getNext();
 var last = this.getLast();
 var pages = this.getPages();
 return this.config.theme.replace(/%HEADER%/, header).replace(/%FIRST%/, first).replace(/%PREV%/, prev).replace(/%PAGES%/, pages).replace(/%NEXT%/, next).replace(/%LAST%/, last);
 }
}

  使用方法:

var params = {//配置分页参数,pageListNum为显示页码按钮的数量:默认为15,perPage为每页显示的记录数:默认为20,pageSign为分页标识码:默认为page, config为分页模版
 pageListNum : 15,
 perPage : 10,
 pageSign : "p",
 config : {
 "header" : '<span style="position:relative;top:8px;left:10px" class="rows">第%CURRENT%------%TOTAL%页</span>',
 'first'  : '<li><a href="%HREF%" aria-label="fisrt"><span aria-hidden="true">首页</span></a></li>',
 'prev'   : '<li><a href="%HREF%" aria-label="Previous"><span aria-hidden="true">上一页</span></a></li>',
 'next'   : '<li><a href="%HREF%" aria-label="Next"><span aria-hidden="true">下一页</span></a></li>',
 'last'   : '<li><a href="%HREF%" aria-label="last"><span aria-hidden="true">尾页</span></a></li>',
 'list'	 : '<li class="%STATUS%"><a href="%HREF%">%NUM%</a></li>',//要输出的分页列表模版
 'theme'  : '<nav><ul class="pagination">%FIRST% %PREV% %PAGES% %NEXT% %LAST% %HEADER%</ul></nav>'
 }
 }
 var p = new pg(req, results[0]['total'], params);
 var limit = p.getLimit();
 var pageList = p.showPage();

      这个分页类的实现思路完全是借用php的分页类实现的,只是把php语言翻译成node而已。因为我的小demo前端是基于bootstrap的,时间紧急,没有支持传入参数来替换显示分页的样式,有空再完善一下。在写的过程中,发现node的封装,很多都是在js层封装的,不似php,都是在c底层封装的,像get、post、cookie、session等值的获取与操作都集成在zend引擎核心里面了,甚至不是作为一个扩展提供,而node.js提供的内置对象,只是把底层基于http协议发送过来的socket连接数据读取到,解析还要靠js层的封装。

转载请注明:飞嗨 » node.js分页类

喜欢 (3)or分享 (0)
发表我的评论
取消评论

表情
粤ICP备15018643号-1