1.分页显示数据
准备工作:启动数据库服务,打开mongo.exe,启动nodejs服务。
浏览器地址:http://localhost:1234/ 会看见显示的数据。
我们要做的是分页显示数据,在预览时我们经常看见,现在news集合只有3条记录,我们增加到10条,作为操作使用。
刷新看见数据全部进来了,我们可以着手分页的工作了。
我们先简单分析分页原理:
首先地址上有当前页参数(get方法) 如变量 currentpage=1第一页,地址变为localhost:1234/?currentpage=1;
每页显示个数 如变量 count=3;
然后就是当前页显示记录 公式(currentpage-1)*3
第1页 0-2记录
第2页 3-5记录
类推;
记录总个数/每页个数 等于总页数,不整除+1页。
我们修改index.js的首页处理,get获取当前页数:
app.get('/',function(req, res){
var currentpage=req.query.currentpage?req.query.currentpage:1;
model.model_index(currentpage,function(items){
res.render('index', { title: 'Express',hello: 'hello world!',arr: items });
});
});
获取参数currentpage的值,没有参数默认在第一页。
修改model.js的处理:
对于查询操作,mongoskin提供了非常丰富的处理,我们查看api,找到处理方法,假如是第一页,那么就该获取0-2记录的数据,
model.model_index=function(currentpage,callback){
var count=3;
var offset=(currentpage-1)*count;
db.bind('news');
db.news.find({},{limit: count, skip:offset}).toArray(function(err, items) {
if (err) throw err;
callback(items);
db.close();
});
};
我对传入的参数做了处理,在find方法加入limit和skip高级处理,skip就是跳到第几条记录开始显示,limit就是往后查询几条,和mysql的limit语句类似。
我们查看首页数据:
显示3条,我们继续处理,我们首先要获取总记录数,然后算出总页数,把这个都要返回给路由程序中:
model.model_index=function(currentpage,callback){
var count=3;
var offset=(currentpage-1)*count;
db.bind('news');
db.news.count({},function(err, len){
if (err) throw err;
db.news.find({},{limit: count, skip:offset}).toArray(function(err, items) {
if (err) throw err;
callback(items,len);
db.close();
});
});
};
使用count方法,第一个是查询参数,这里可以不写,其实查询参数很有用的,比如我们要查性别是女的就要加入这个设置,
回调len就是总记录数,我们返回到路由处理:
app.get('/',function(req, res){
var currentpage=req.query.currentpage?req.query.currentpage:1;
model.model_index(currentpage,function(items,len){
res.render('index', { title: 'Express',hello: 'hello world!',arr: items,len:len });
});
});
修改index.html模板页面:
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<p><a href="/hello"><%= hello %></a></p>
<ul>
<% for(var i=0; i<arr.length; i++) {%>
<li><a href="/list"><%= arr[i].title %></a><span><%= arr[i].text %></span></li>
<% } %>
</ul>
<h1><%= len %></h1>
</body>
</html>
查看,显示为10,和总记录相同,下面我们对处理一气呵成:
修改model.js,把总页数,记录内容,总页数,全部返回:
model.model_index=function(currentpage,callback){
var count=3;
var offset=(currentpage-1)*count;
db.bind('news');
db.news.count({},function(err, len){
if (err) throw err;
var allpage=len%count==0?len/count:Math.floor(len/count)+1;
db.news.find({},{limit: count, skip:offset}).toArray(function(err, items) {
if (err) throw err;
callback(items,len,allpage);
db.close();
});
});
};
index.js:
app.get('/',function(req, res){
var currentpage=req.query.currentpage?req.query.currentpage:1;
model.model_index(currentpage,function(items,len,allpage){
res.render('index', { title: 'Express',hello: 'hello world!',arr: items,len:len,allpage:allpage,cur:currentpage });
});
});
index.html:
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<p><a href="/hello"><%= hello %></a></p>
<ul>
<% for(var i=0; i<arr.length; i++) {%>
<li><a href="/list"><%= arr[i].title %></a><span><%= arr[i].text %></span></li>
<% } %>
</ul>
<div>
<%
for(var i=1;i<=allpage;i++){
%>
<a href="/?currentpage=<%= i %>"><%= i %></a>
<%
};
%>
总页数:<span><%= allpage %></span>
当前在<span><%= cur %></span>页
共<span><%= len %></span>记录
</div>
</body>
</html>
我们预览一下:
虽然长得丑,不过也算是比较全了,这只是最最简单分页,在现实上其实还要有很多处理,比如当前页高亮,页数过渡怎么显示,还有上一页,下一页,第一页,最后一页,跳页的处理等,可以自己研究。
总结:
针对数据库的api:
count方法,第一个参数值query,回调返回总页数
find方法,第一个参数query,还可以写高级的skip和limit跳记录和限制处理,和sql语句的select很像skip如同mysql的limit
toArray 转为数组形式,方便输出显示,和mysql的mysql_fetch_toarray很像。
还有一个sort设置,在find方法里,和mysql的排序一样
2.ajax加载更多显示数据
我们还是使用news集合数据做处理,不过采用ajax的形式,针对/hello做处理,在hello.html引入jq类库。
我们把jq类库放在public的javascripts下,
hello.html引用
<!DOCTYPE html>
<html>
<head>
<title>hello</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<ul>
<% for(var i=0; i<arr.length; i++) {%>
<li><span><%= arr[i].name %></span></li>
<% } %>
</ul>
</body>
<script src="javascripts/jquery-1.10.2.js"></script>
</html>
我们会感觉很困惑,hello.html在views下,jq类库在public下,为何引用时直接javascripts/jquery-1.10.2.js就可以了,
不应该是../public/javascripts/jquery-1.10.2.js吗?
我们打开app.js,找到这个部分:
__dirname是node的全局对象,返回app.js的目录,这个方法就是针对静态模板,路径的公用部分是app.js路径/public。
path模块的join是路径拼接方法。
我们已经有了分页的基础,对ajax的分页实现,加快速度:
index.js路由处理:
app.get('/hello', function(req, res){
var currentpage=req.query.currentpage?req.query.currentpage:1;
model.model_index(currentpage,function(items){
res.render('hello', { arr: items });
});
});
如果没有参数,显示第一页;
model.js:
model.model_hello=function(currentpage,callback){
var count=3;
var offset=(currentpage-1)*count;
db.bind('news');
db.news.find({},{limit: count, skip:offset}).toArray(function(err, items) {
if (err) throw err;
callback(items);
db.close();
});
};
返回拿到的的跳页数据;
hello.html先测试显示:
<!DOCTYPE html>
<html>
<head>
<title>hello</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<ul>
<ul>
<% for(var i=0; i<arr.length; i++) {%>
<li><a href="/list"><%= arr[i].title %></a><span><%= arr[i].text %></span></li>
<% } %>
</ul>
</ul>
</body>
<script src="javascripts/jquery-1.10.2.js"></script>
</html>
hello.html显示了3条记录,我们在页面加一个”加载更多“按钮,然后写ajax请求:
<!DOCTYPE html>
<html>
<head>
<title>hello</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<ul>
<ul id="list">
<% for(var i=0; i<arr.length; i++) {%>
<li><a href="/list"><%= arr[i].title %></a><span><%= arr[i].text %></span></li>
<% } %>
</ul>
</ul>
<input type="button" id="more" value="加载更多">
</body>
<script src="javascripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
var more=1;
$("#more").click(function(){
more+=1;
$.ajax({
url: "/hellomore",
type: "GET",
data:{more:more},
dataType: "json",
error: function(){
alert('Error');
},
success: function(data,status){
for(var i=0;i<data.length;i++){
$("#list").append('<li><a href="/list">'+data[i].title+'</a><span>'+data[i].text+'</span></li>');
};
}
});
});
});
</script>
</html>
针对ajax我们加入路由处理:
app.get('/hellomore', function(req, res){
model.model_hello(req.query.more,function(items){
res.send(items);
});
});
res.send方法就是返回数据,res.render是返回给模板。
预览一下效果:
点击“加载跟多”
我们知道ajax是异步请求,就好像偷偷的去指定地方那东西,然后获取到,在以js插入到标签里,也就无刷新处理了。
我们是发送get请求,每次给页数加1,偷偷拿到返回的数据,插入到ul内部。
总结:
index.js,针对首页和hello做了处理
var formidable = require('formidable');
var fs = require('fs');
var crypto = require('crypto');
var model = require('../model/model');
function rout(app){
app.get('/',function(req, res){
var currentpage=req.query.currentpage?req.query.currentpage:1;
model.model_index(currentpage,function(items,len,allpage){
res.render('index', { title: 'Express',hello: 'hello world!',arr: items,len:len,allpage:allpage,cur:currentpage });
});
});
app.get('/hello', function(req, res){
var currentpage=req.query.currentpage?req.query.currentpage:1;
model.model_hello(currentpage,function(items){
res.render('hello', { arr: items });
});
});
app.get('/hellomore', function(req, res){
model.model_hello(req.query.more,function(items){
res.send(items);
});
});
app.get('/list', function(req, res){
res.render('list', { text: req.query.id });
});
app.get('/login', function(req, res){
res.render('login');
});
app.post('/logincheck', function(req, res){
var user= req.body.user;
var pass= req.body.pass;
if(user=="tom" && pass=="tom"){
res.redirect('/');
}else{
res.redirect('/login');
};
});
app.get('/file', function(req, res){
res.render('file');
});
app.post('/upfile', function(req, res){
//code
var form = new formidable.IncomingForm();
form.uploadDir = "./upload";
form.parse(req, function(err, fields, files) {
if (err) {
res.redirect('/file');
}
var tmp_path, target_path;
if (files.file.size > 0) { //表示有文件上传
tmp_path = files.file.path;//内存中的文件,当前文件目录
var picType = files.file.name.split(".")[1];//后缀名
//移动目的目录
target_path = './public/images/pic_1.' + picType;
//同步方式移动文件
fs.renameSync(tmp_path, target_path);
}else{
res.redirect('/file');
};
});
});
app.get('/fs', function(req, res){
fs.writeFile('./fs/me/1.txt', 'read me','utf8',
function (err) {
if (err) throw err;
});
});
app.get('/crypto', function(req, res){
var pass="admin";
var md5 = crypto.createHash('md5');
var mpass=md5.update(pass).digest('hex');
var rmpass=mpass.substring(2);
res.render('crypto', { res:pass,resm:mpass,resrm:rmpass });
});
app.get('/globals', function(req, res){
res.render('globals', { res:__dirname+":"+__filename });
});
};
exports.rout=rout;
model.js加入查询处理等
var config = require('./config');
var mongo = require('mongoskin');
var db = mongo.db(config.connect, {native_parser:true});
var model={};
model.model_index=function(currentpage,callback){
var count=3;
var offset=(currentpage-1)*count;
db.bind('news');
db.news.count({},function(err, len){
if (err) throw err;
var allpage=len%count==0?len/count:Math.floor(len/count)+1;
db.news.find({},{limit: count, skip:offset}).toArray(function(err, items) {
if (err) throw err;
callback(items,len,allpage);
db.close();
});
});
};
model.model_hello=function(currentpage,callback){
var count=3;
var offset=(currentpage-1)*count;
db.bind('news');
db.news.find({},{limit: count, skip:offset}).toArray(function(err, items) {
if (err) throw err;
callback(items);
db.close();
});
};
module.exports=model;
index.html
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<p><a href="/hello"><%= hello %></a></p>
<ul>
<% for(var i=0; i<arr.length; i++) {%>
<li><a href="/list"><%= arr[i].title %></a><span><%= arr[i].text %></span></li>
<% } %>
</ul>
<div>
<%
for(var i=1;i<=allpage;i++){
%>
<a href="/?currentpage=<%= i %>"><%= i %></a>
<%
};
%>
总页数:<span><%= allpage %></span>
当前在<span><%= cur %></span>页
共<span><%= len %></span>记录
</div>
</body>
</html>
hello.html ajax请求,注意jq类库的引入
<!DOCTYPE html>
<html>
<head>
<title>hello</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<ul>
<ul id="list">
<% for(var i=0; i<arr.length; i++) {%>
<li><a href="/list"><%= arr[i].title %></a><span><%= arr[i].text %></span></li>
<% } %>
</ul>
</ul>
<input type="button" id="more" value="加载更多">
</body>
<script src="javascripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
var more=1;
$("#more").click(function(){
more+=1;
$.ajax({
url: "/hellomore",
type: "GET",
data:{more:more},
dataType: "json",
error: function(){
alert('Error');
},
success: function(data,status){
for(var i=0;i<data.length;i++){
$("#list").append('<li><a href="/list">'+data[i].title+'</a><span>'+data[i].text+'</span></li>');
};
}
});
});
});
</script>
</html>
来源:oschina
链接:https://my.oschina.net/u/2352644/blog/552713