文章列表分页+二级导航

来源:互联网 发布:汽车行业概况知乎 编辑:程序博客网 时间:2024/05/18 16:16

文章列表分页

访问/article/list-:page.html

//截取数据select * from article order by id desc limit ?,3  截取3个数据
// 分页列表router.get('/article/list-:page.html',(req,res)=>{    console.log(req.params);    sql('select * from article order by id desc limit ?,3',[(req.params.page-1)*3],(err,data)=>{        if(err){            res.send('错误');            return;        }        res.locals.mark = false;        res.locals.active = req.params.page-1;        res.render('article',{ data:data });    });});

article.ejs

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title>    <style type="text/css">        * {margin: 0; padding: 0;}        a {text-decoration: none;}        ul,li {list-style: none;}        body {font-family: "Microsoft yahei";}        ul {padding: 20px;}        li {width: 100%; height: 40px; line-height: 40px; background: #fafafa; border: 1px solid #ddd; cursor: pointer; border-radius: 5px;}        li a{display: block; width: 100%; height: 100%; color: #222; font-size: 16px; text-indent: 1em;}        li:hover{background: #EDEDED;}        li span {font-size: 14px; color: #454545;}        li span.time {margin-left: 20px; color: #777;}        li span.pageview {float: right; margin-right: 20px;}        #paging {float: right; width: 170px; height: 30px; margin: 0 20px;}        #paging a {display: block; float: left; width: 30px; height: 30px; line-height: 30px; margin: 0 5px; border: 1px solid #ddd; background: #fafafa; text-align: center; color: #222; border-radius: 5px;}        #paging a.on {background: #EDEDED;}    </style>    <script src="/js/jquery.js"></script></head><body><% if(data.length == 1 && locals.mark) { %>    <h1>文章标题: <%= data[0]['title'] %></h1>    <p>标签:<%= data[0]['tag'] %></p>    <p>作者:<%= data[0]['author'] %></p>    <p>时间:<%= data[0]['time'] %></p>    <p>内容:<%= data[0]['content'] %></p>    <a href='/article'>返回列表</a>    <h3>评论:</h3>        <% if( locals.comment ){ %>            <% for(var i in locals.comment){ %>                <p><span> <%=  %></span> <%= locals.comment[i]['content'] %></p>            <% } %>        <% } %>    <form action="/article/<%= data[0]['id'] %>.html" method="post" >        <input type="text" name="comment">        <input type="submit" name="submit" value="发表评论">    </form><% }else{ %>    <h1>文章列表:</h1>    <ul>    <% for(var i in data){ %>        <li><a href='/article/<%- data[i]["id"] %>.html'> <%- data[i]['title'] %> <span class='tag'> <%- data[i]['tag'] %> </span><span class='time'>( <%- data[i]['time'] %> )</span><span class='pageview'><%- data[i]['pageview'] %></span></a></li>    <% } %>    </ul>    <% if( locals.active !== undefined ){ %>    <div id='paging' active='<%= locals.active %>'>        <a href="/article/list-1.html" class="on">1</a>        <a href="/article/list-2.html">2</a>        <a href="/article/list-3.html">3</a>        <a href="/article/list-4.html">4</a>    </div>    <script>        var paging = $("#paging");        var active = paging.attr('active');        paging.children().removeAttr('class');        paging.children()[active].className = 'on';    </script>    <% } %><% } %></body></html>

这里写图片描述

访问量控制

每天一次算访问量+1设置cookie控制

访问详情页时, /article/:id.html

router.get('/article/:id.html',(req,res)=>{    // 访问/article/1.html    // 新的传值方法 :param    //req.params  同时接收get , post , 其它 提交数据的形式    console.log(req.params);    sql('select * from article where id = ?',[req.params.id],(err,data)=>{        if(data.length == 0){            // 需要res.status(404)设置状态码            res.status(404).render('err');            return;        }        // 访问量 每个用户限制cookie   每次+1        console.log(Number(data[0]['pageview'])+1);        // 判断有没访问量cookie        if(req.cookies['article'] == undefined){            res.cookie('article',{ id: req.params.id },{ maxAge: 1000*60*60*24});            sql('update `article` set `pageview`= ? where `id`= ?',[Number(data[0]['pageview'])+1,req.params.id],(err,data3)=>{            });        }        console.log(req.cookies);        // 只有访问不同文章 访问量才加一  未解决?? 访问不同文章且今天没有访问过        if(req.cookies['article'].id !== req.params.id ){            // 设置 res.cookie 修改访问量数据            sql('update `article` set `pageview`= ? where `id`= ?',[Number(data[0]['pageview'])+1,req.params.id],(err,data3)=>{            });            res.cookie(`article`,{ id: req.params.id },{ maxAge: 1000*60*60*24});        }        //读取该文章的评论        sql('select * from comment where articleid = ?',[req.params.id],(err,data2)=>{            if(err){                res.send('错误');                return;            }            res.locals.mark = true;            res.locals.comment = data2;            res.render('article',{ data:data });        })    });});

给数据库表article 添加访问量 pageview

这里写图片描述

二级导航

使用promise控制异步

创建表nav

结构这里写图片描述

CREATE TABLE `book`.`nav`( `id`     INT(11)  NOT NULL AUTO_INCREMENT, `navid` varchar(64)     NOT NULL ,  `level` varchar(64) NOT NULL ,  PRIMARY KEY (`id`)  )ENGINE = InnoDB CHARSET = utf8;

前端想要的数据结构

这里写图片描述


因为查询数据库要时间,想要把data完整的返回给模板 需要等待它查询完

所以使用Promise控制异步

查询成功nav.js

const sql = require('./module/mysql.js');let fn = function(onedata,i){    return new Promise(function(resolve,reject){        sql('SELECT * FROM `nav` where level = 2 and `navid` = ? ',[onedata[i]['navid']],(err,twodata)=>{            // console.log(data);            onedata[i]['child'] = twodata;            // console.log(onedata);            // res.render onedata想完整的返回给模板  需要使用promise            resolve();        })    });}sql('SELECT * FROM `nav` where `level` = 1',(err,onedata)=>{    // console.log(onedata);    let arr = [];    for(let i in onedata){         // var 不能保存 i        arr[i] = fn(onedata,i)    }    // 接受一组promise对象, 等待它们成功才执行then    Promise.all(arr).then(function(){        // 响应模板        console.log(onedata);    })});
封装

每个页面可能用到导航,暴露出去

const sql = require('./module/mysql.js');let fn = function(onedata,i){    return new Promise(function(resolve,reject){        sql('SELECT * FROM `nav` where level = 2 and `navid` = ? ',[onedata[i]['navid']],(err,twodata)=>{            // console.log(data);            onedata[i]['child'] = twodata;            // console.log(onedata);            // res.render onedata想完整的返回给模板  需要使用promise            resolve();        })    });}module.exports = function(req,res,cb){    sql('SELECT * FROM `nav` where `level` = 1',(err,onedata)=>{        // console.log(onedata);        let arr = [];        for(let i in onedata){            // var 不能保存 i            arr[i] = fn(onedata,i)        }        // 接受一组promise对象, 等待它们成功才执行then        Promise.all(arr).then(function(){            // 响应模板            cb(onedata); //将数据输出        })    });}

app.js引入

nav = require('./nav');app.use(function(req,res,next){   //!!没有next页面会一直加载    // 只加载一次导航    if(!res.locals.nav){        nav(req,res,(data)=>{//使用回调等它查询完 再赋值            res.locals.nav = data;        });    }})

访问/nav 给缓冲时间

router.get('/nav', (req,res)=>{    // 加载数据要时间    setTimeout(function(){        console.log(res.locals.nav);        res.render('nav');    },500)})

响应模板 nav.ejs

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><body><ul>    <% for(var i in locals.nav){ %>       <li>           <%= locals.nav[i]['title'] %>           <ul>               <% for(var j in locals.nav[i]['child']){ %>               <li><%= locals.nav[i]['child'][j]['title'] %></li>               <% } %>           </ul>       </li>   <% } %></ul></body></html>
原创粉丝点击