node.js项目开发流程及bug汇总
1.新建文件夹,命名为students;
2.在powershell中在当前目录下使用 npm init -y 生成package.json
3.在students目录下新建app.js文件,编辑代码
4.在students目录下新建文件夹 model,并在目录下新建文件connect.js用户放置数据库连接的代码。
5.在此记录一个bug.
//引入模板引擎 const template = require('art-template'); //配置模板的根目录 !!!这个必须放在app.js文件中,如果放置其它文件有可能导致路由无法响应资源 template.defaults.root = path.join(__dirname, 'views');
总结如下:1)当问题出现时一定要仔细阅读给出的错误信息,根据信息推导出现了什么问题。这个bug在错误信息中已经给出来了:Unhandled Promise Rejection Warning: TemplateError: template not found: ENOENT: no such file or directory, open 'F:\360MoveData\Users\20122\Desktop\web练习\11.9练习\students\route\views\list.art' 很显然,list.art文件未找到,那原因很可能就是路径出来问题,那么此时就要核查该文件的加载路径,通过核查发现,改文件 的路径之前经过根目录的配置,但是由于配置文件路径的改变,导致__dirname的路径发生变化,导致配置的根目录发生改变,所以,该配置代码(涉及路径的代码)不能轻易改变位置。
2)在进行见项目的模块化开发的时候一定要注意文档引入的路径问题例如:通过require()引入文件或者模块的时候。
6.bug记录
bootstrap模态框无法弹出,原因在于自定义的属性的中包含了空格,导致失效
7.bug记录
// 将文章集合的构造函数导入到当前文件当中 const { Article } = require('../../model/article'); module.exports = async(req, res) => { //这是一个标识,表示用户访问的是用户管理页面 req.app.locals.currentLink = 'article'; //查询所有文章数据 let articles = await Article.find().populate('author'); //解决方案二 如下两行 //let articles_string = JSON.stringify(articles); //let article = JSON.parse(articles_string); //链式调用populate()使得服务器端出错 //在后面链式调用.lean() 告诉mongoose返回普通对象 不返回mongoose文档对象即可解决此bug // res.send(articles); res.render('admin/article', { article: article }); }
报错信息:
上图是有错误处理中间件的情况下的报错。
下图是暂时注释掉错误中间件的情况下的报错。
8、分页实现总结
//从req中获得当前的请求页码 let page = req.query.page || 1; //规定每页显示的总数 let pagesize = 2; //查询数据库中数据的总数 let pageCount = await Article.countDocuments({}); //计算显示的总页数 用于动态生成合适的<li></li> let total = Math.ceil(pageCount / pagesize); //根据当前请求的页码page计算跳过多少个开始查询 let start = (page - 1) * pagesize; //根据当前页码 跳过start 个数据 连续查询 pagesize 个数据返回给articles let articles = await Article.find().limit(pagesize).skip(start); //想模板渲染数据 同时传入当前请求的页码(方便实现上一页 下一页的功能) //同时传入 total 用于生成合适的li res.render('admin/article', { articles: articles, page: page, total: total });
//需要渲染的模板模块 <ul class="pagination"> <li> //上一页功能实现 <a href="/admin/article?page={{page>1?page-1:page}}"> <span>«</span> </a> </li> //动态生成li <%for(var i=1;i<= total;i++) {%> <li><a href="/admin/article?page=<%=i%>">{{i}}</a></li> <%}%> <li> //下一页功能实现 <a href="/admin/article?page={{page<total?page+1:page}}"> <span>»</span> </a> </li> </ul>
9.bug记录
对通过模板渲染的页面中的元素进行监听,出现了部分监听失效的问题。监听的代码如下:
{{block 'script'}} <script type="text/javascript"> $('#deleteArti').on('click', function() { var id = $(this).attr('data-id'); $('#deleteArticleId').val(id); }); </script> {{/block}}
通过测试发现,在获取元素的时候出现了问题,由于监听的元素是通过循环生成的,如下:
{{each articles.records}} <tr> <td>{{@$value._id}}</td> <td>{{$value.title}}</td> <td>{{dateFormat($value.publishDate,'yyyy-mm-dd hh:mm:ss')}}</td> <td>{{$value.author.username}}</td> <td> <a href="/admin/article-edit?id={{@$value._id}}" class="glyphicon glyphicon-edit"></a> //此处通过id属性来设置i元素 <i data-id="{{@$value._id}}" id="deleteArti"></i> </td> </tr> {{/each}}
是通过id属性来设置的,同一页面生成多n个i元素,就会出现n个id属性,当通过jQuery$('#')来获取id标记的元素的时候,一个页面只会有一个元素可以获取到。
当通过class属性来标记i元素的时候就不会发生这个问题。就其原因,就是id和class的区别:
id具有唯一性,只能一个html只能用一次,多的将会失效。而class则可以实现批量类别标识,这样就可以获取到批量的具有该class的元素。
所以在模板中,一定要在获取元素时,一定要注意小心使用id和class
10、mongooDB数据库添加账号
1)以系统管理员的方式运行powershell
2)连接数据库mongo
3)查看数据库 show dbs
4)使用use admin 切换到admin数据库
5)使用db.createUser()创建超级管理员账号
6)使用use blog 切换到blog数据库
7)使用db.createUser()为blog添加普通管理员账号
8)使用exit退出数据库
9)使用net stop mongodb停止服务
10)使用mongod --remove移除MongoDB服务
11)创建mongodb服务使用mongod --logpath='' --dbpath='' --install --auth 来设置mongod.log的地址以及data的地址 安装并且使用--auth使数据库访问必须要有账号和密码
12)启动mongodb服务 net start mongodb
11)在项目中使用账号连接数据库
代码模板:mongoose.connect('mongodb://user:pass@localhost:port/database')
mongoose.connect('mongodb://用户名:密码@localhost:端口号/数据库名称')