为了更好的掌握nodej.js,于是最近用node.js写了个小demo,发现node.js的库相对php还是少了许多。对于常用的分页类也没找到,于是就基于bootstrap自己写了一个。
不过,不得不吐槽一下,node.js的异步也很坑,,,在对数据库select的时候是异步的,所有依赖数据库返回的逻辑都要写在回调函数里面,阔是,如果有多个逻辑需要数据库层层返回,无限的层层嵌入,,,oh,god!还好,分页类嵌套两层就阔以了。当然,借助库,这些异步操作也可以改成同步进行。可见,异步虽然流弊闪闪也有它的缺点,当然咯,go语言的协程可以解决异步操作,但是代码表现形式依然是同步的,我大php在5.5版本中也加入了对协程的支持。
地址:https://github.com/liufee/nodejs
分页效果:
/*
* @author liufee <job@feehi.com>
* @link https://blog.feehi.com/wp-content/uploads
* @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分页类

