开始nodejs+express的学习+实践(7)

1.分页显示数据

准备工作:启动数据库服务,打开mongo.exe,启动nodejs服务。

浏览器地址:http://localhost:1234/ 会看见显示的数据。

我们要做的是分页显示数据,在预览时我们经常看见,现在news集合只有3条记录,我们增加到10条,作为操作使用。

开始nodejs+express的学习+实践(7)_第1张图片

刷新看见数据全部进来了,我们可以着手分页的工作了。

我们先简单分析分页原理:

首先地址上有当前页参数(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语句类似。

我们查看首页数据:

开始nodejs+express的学习+实践(7)_第2张图片

显示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,和总记录相同,下面我们对处理一气呵成:

开始nodejs+express的学习+实践(7)_第3张图片

修改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>

我们预览一下:

开始nodejs+express的学习+实践(7)_第4张图片开始nodejs+express的学习+实践(7)_第5张图片

虽然长得丑,不过也算是比较全了,这只是最最简单分页,在现实上其实还要有很多处理,比如当前页高亮,页数过渡怎么显示,还有上一页,下一页,第一页,最后一页,跳页的处理等,可以自己研究。

总结:

针对数据库的api:

  1. count方法,第一个参数值query,回调返回总页数

  2. find方法,第一个参数query,还可以写高级的skip和limit跳记录和限制处理,和sql语句的select很像skip如同mysql的limit

  3. toArray 转为数组形式,方便输出显示,和mysql的mysql_fetch_toarray很像。

  4. 还有一个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,找到这个部分:

开始nodejs+express的学习+实践(7)_第6张图片

__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是返回给模板。

预览一下效果:

开始nodejs+express的学习+实践(7)_第7张图片

点击“加载跟多”

开始nodejs+express的学习+实践(7)_第8张图片

我们知道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>

你可能感兴趣的:(开始nodejs+express的学习+实践(7))