序
今天,我们将制作一个简单的新闻发布系统。系统的第一阶段不需要太难。它主要有以下功能
新闻类型管理
新闻管理(带图片上传功能)
新闻浏览
虽然功能不多,但也涵盖了很多基本操作。添加、删除、检查和更改程序以及上传附件就足够了。让我们今天开始学习吧
准备工作/即将工作
根据昨天的折腾,我们已经有了nodeJS和mongoDB环境,现在可以直接构建新的工程文件和数据库文件
第一步是打开命令符号,切换到D盘,然后输入
复制代码如下:D:express -e新闻
所以系统会自动愉快地构建基本环境
显然,许多模块并不依赖于它。此时,将直接测试昨天的package.json:
复制代码的代码如下: { ' name ' : ' application-name ',' version' :' 0.0.1 ',' private' : true,' scripts ' : { ' start ' : ' node app . js ' }。依赖项' : { 'express': '3.4.8 ',' ejs': '* ',' mongodb ' : ' * ' }
然后切换到项目目录:
复制代码如下:nmp安装
所有相关文件都已关闭,然后我们输入它们
复制代码如下:d3360 newsnode app express服务器侦听端口3000
所以我们的程序运行的很愉快,打开网站的时候真的没问题
PS:这里有一个问题需要注意。我们下载的文件不是UTF-8编码,所以中文可能有乱码,文件编码需要大家统一。
当程序运行时,它需要数据库相关的配置
(1)首先在mongoDB目录中创建新的新闻文件夹
为项目添加配置文件settings.js
复制的代码代码如下:模块。exports={ cookie secret : ' my news ',db:' news ',host 3360 ' localhost ' };
创建一个新的models目录,并创建一个新的db.js
复制代码如下:VAR设置=要求('./settings '),db=require ('MongoDB ')。db,connection=require ('MongoDB ')。连接,服务器=必需(' MongoDB ')。服务器;模块.导出=新的db(设置. Db,新的服务器(设置.主机,连接。DEFAULT_PORT),{ safe : true });
在桌面上创建新的news.bat程序
复制代码如下:d 3360 MongoDB bin MongoDB . exe-dbpath d : MongoDB news
未来要启动数据库,我们只需要运行它,所以我们的前期准备工作基本结束了
但是这里有两个讨厌的地方,一个是每次启动新闻节目都很讨厌,另一个是一切都需要重启,所以我们先在这里解决这两个问题
(1)在桌面上创建new news_app.bat,稍后运行即可启动程序
复制代码如下:node d:newsapp
主管是一个过程保护程序。我们可以用它来帮助我们重新启动程序,首先遵循它,然后调整我们的node_app.bat
复制代码如下:supervisor d:newsapp
当然,您需要在以下时间之前安装它:
复制代码如下:npm install -g supervisor
这样,修改文件后,就不需要手动重启了(需要将news_app放在项目目录中),所以准备工作到此结束
项目结构
在第一步之后,我们需要考虑项目结构
(1)主页是索引,所有新闻类型和新闻项目都将在其中列出
每个新闻项目有三个按钮:编辑/删除/查看
主页有添加新闻按钮(添加时可上传图片)
基本功能如上
因此,我们删除了应用程序中的路由功能,并将所有路由放入索引中
复制代码如下://将路由函数放入index//app.get ('/',routes . index);//app.get('/users ',user . list);路线(app);
复制的代码如下:模块。exports=function(app){//home page,也就是现在的home page app。get ('/',function (req,res) {res.render ('index ',{ title : ' express ' });});App.get ('/add ',函数(req,RES){ RES . send(' add news request ');});APP.get ('/delete ',函数(req,RES){ RES . send(' delete news request ');});App.get ('/view ',函数(req,RES){ RES . send(' view news request ');});Get ('/update ',函数(req,RES) {res.send('修改新闻请求');});};
第一步很简单,因为添加新闻应该有一个单独的页面,当你点击添加按钮时会有其他处理,所以你必须在内部细分每个请求。现规定如下:
/default页面,通过删除按钮显示所有类型和新闻
/add进入添加新闻页面
/addNews添加新闻特定的帖子请求地址(单击按钮时的响应)
/delete删除新闻请求
/查看特定新闻查询
然后稍微修改一下上面的路线:
复制的代码如下:模块。exports=function(app){//home page,也就是现在的home page app。get ('/',function (req,res) {res.render ('index ',{ title : ' express ' });});App.get ('/add ',函数(req,RES){ RES . send(' add news page ');});App。post ('/addnews ',函数(req,RES){ RES . send(' process add news request ');});APP.get ('/delete ',函数(req,RES){ RES . send(' delete news request ');});App.get ('/view ',函数(req,RES){ RES . send(' view news request ');});};
所以我们需要建立几个新的模板来组织我们的网页。这里我们不先分开头部和尾部,只是最简单的一页
增加了Add和view模板文件,暂时与index.ejs保持一致,与导航修改相关
复制的代码如下:模块。exports=function(app){//home page,也就是现在的home page app。get ('/',function (req,res) {res.render ('index ',{ title : ' express ' });});Get ('/add ',函数(req,RES) {res.render ('add ',{ title : ' add news page ' });});App。post ('/addnews ',函数(req,RES){ RES . send(' process add news request ');});APP.get ('/delete ',函数(req,RES){ RES . send(' delete news request ');});Get ('/view ',函数(req,RES) {res.render ('view ',{ title : ' view news request ' });});};
此时,项目结构结束
数据操作
整体结构出来后,我们需要对数据进行操作:
增加数据(增加新闻)
显示数据(显示新闻)
删除数据(删除新闻)
本来也涉及到类型操作,但是做的时候就丢了。暂时别管他,因为第一次做的时候很容易搞混
添加新闻
这里,我们不使用表单提交,我们使用ajax.顺便说一下,我们在这里引入了zepto库,所以我们的页面变成了这样
复制代码如下:DOCTYPE html html head title %=title %/title link rel='样式表' href='/样式表/style . CSS '/script src=' http : JavaScript/Zepto . js ' type=' text/JavaScript '/script/head dy h1 %=title %/h1 Div title:输入类型=' text ' id=' title '/Div内容:text area id=' content '/text area/Div输入类型=' button' type=' button' id=' ok 'ready (function () {$ ('# ok '))。单击(function(){ var param={ };param.title=$('#title ')。val();param.content=$('#content ')。val();$.post ('/addnews ',param,function () {console.log('添加成功');});});});/脚本/正文/html
虽然还没有请求响应程序,但是数据不会被处理,这里也没有附件(现在只允许一个附件),所以修改代码加图片:
PS:更麻烦的是图片用ajax处理有点麻烦,所以我们切换回这里的表单操作,不然需要多长时间.
复制代码代码如下: html标题标题%=标题%/标题链接rel='样式表href='/样式表/style。CSS/head body h1 %=title %/h1表单enctype=' multipart/form-data '方法=' post '操作='/addNews ' div标题:输入类型=' text ' id=' title ' name=' title '/div/div图片:输入类型=' file ' id=' pic ' name=' pic '/div内容:文本区域id=' content ' name=' content '/文本区域/div输入类型='submit' id='ok '值='添加新闻//div/表单/正文/html
这个样子就不需要过多的考虑附件问题,先暂时如此吧,现在先处理请求程序,这里先在公众的里面新建新闻文件夹用于存储其图片
模型
在模型文件夹新增新闻。射流研究…文件,为其构建实体,并赋予新增查询相关操作:
复制代码代码如下:var mongodb=require(' ./db ');
功能新闻(标题、内容、图片){ this . title=title this . content=content this . pic=pic//保存存储路径};模块。导出=新闻;//存储数据News.prototype={ save:函数(回调){ var Date=new Date();var time={ date: date,year: date.getFullYear(),month : date。getfullyear()'-'(日期。getmonth()1),第:天日期。getfullyear()'-'(日期。getmonth()1)'-'日期。getfullyear(),分钟日期。getfullyear()'-'(日期。getmonth()1)'-'日期。get date()“-”日期。gethours()' 3: '(日期。getminutes())11' 0 '日期。getminutes(): date。getminutes())}//数据存储对象var news={ title: this.title,content: this.content,pic: this.pic,//图片处理最后来说,现在先乱存time : time };//打开数据连接,打开就是一个回调.mongodb.open(函数(err,db) { //错误就退出if(err){ return callback(err);} //打开新闻集合db.collection('news ',函数(err,collection){ if(err){ MongoDB。close();返回回调(错误);} //写入集合(写入数据库)collection.insert(news,{ safe: true },function(err){ return callback(err);});回调(null);//err为null });});}};
于是,写入数据库的程序就有了,这里我们来试试能不能插入数据库,当然需要修改路由处的程序
PS:路由处当然不能写过多逻辑代码,这个文件以后还得分离
这个时候/addNews里面的逻辑需要改变
复制代码代码如下:app.post('/addNews ',函数(req,RES){ var title=req。尸体。标题;var内容=请求。尸体。内容;var pic=req。尸体。picvar新闻=新新闻(标题、内容、图片)news.save(函数(呃,数据){ res.send(数据);})});
查询下,问题不大,现在要解决的就是附件问题了
上传图片
上传图片功能表达本身就支持了快递通过bodyParser解析请求体,然后便可通过他上传文件了,其内部使用了可怕的
这里将app.js里面的app.use(express.bodyParser())改为:
复制代码代码如下: app。使用(快递。正文解析器({ keepextensions 3360 true,uploadDir: ' ./public/news ' });
打开index.js,在前面加一行代码:
复制代码代码如下:fs=require('fs '),
修改一下指数文件:
复制代码代码如下:app.post('/addNews ',函数{ for(req。文件中的var I){ if(req。文件[I]==0){//同步方式删除一个文件fs.unlinkSync(req.files[i]).路径);console.log('成功删除了一个空文件');} else { var path=' ./public/news/' req.files[i].姓名;//使用同步方式重命名一个文件fs.renameSync(req.files[i]).路径,路径);console.log('sunccess重命名为文件');} }//var title=req。尸体。标题;//var content=req。尸体。内容;//var pic=req。尸体。pic//var news=new News(标题、内容、pic)//news.save(函数(呃,数据){//res.send(数据);//})});
这个时候选取文件后点击添加新闻,我们的文件就上传上去了
这个时候,我只需要将文件名记录在数据库即可,文件目录里面就有图片了
复制代码代码如下:app.post('/addNews ',函数(req,RES){ var pic=null;对于(请求。文件中的var I){ if(req。文件[I]==0){//同步方式删除一个文件fs.unlinkSync(req.files[i]).路径);console.log('成功删除了一个空文件');} else { var path=' ./public/news/' req.files[i].姓名;//使用同步方式重命名一个文件fs.renameSync(req.files[i]).路径,路径);console.log('sunccess重命名为文件');} pic=req.files[i].姓名;} var title=req。尸体。标题;var内容=请求。尸体。内容;var新闻=新新闻(标题、内容、图片)news.save(函数(呃,数据){ res.send(数据);}) res.send('a href=' ./'请求成功,返回首页/a ');});
数据库中有数据了,我们目录也有文件了,现在只需要将数据读出来了
PS:放假兄弟们催的凶,要出去喝酒了
读取数据
第二步当然是读取数据,首先是首页的数据读取:
复制代码代码如下:var mongodb=require(' ./db ');功能新闻(标题、内容、图片){ this . title=title this . content=content this . pic=pic//保存存储路径};模块。导出=新闻;//存储数据News.prototype={ save:函数(回调){ var Date=new Date();//数据存储对象var news={ title: this.title,content: this.content,pic: this.pic,//图片处理最后来说,现在先乱存date : date };//打开数据连接,打开就是一个回调.mongodb.open(函数(err,db) { //错误就退出if(err){ return callback(err);} //打开新闻集合db.collection('news ',函数(err,collection){ if(err){ MongoDB。close();返回回调(错误);} //写入集合(写入数据库)collection.insert(news,{ safe: true },function(err){ return callback(err);});回调(null);//err为null });});}};//读取文章及其相关信息News.get=函数(id,回调){ //打开数据库mongodb.open(函数(err,db){ if(err){ return callback(err);} db.collection('news ',函数(err,collection){ if(err){ MongoDB。close();返回回调(错误);} var query={ }if(id){ query。id=id} //根据询问对象查询文章collection.find(查询)。排序({ date: -1 }).toArray(函数(错误,数据){ MongoDB。close();if(err){ return callback(err);//失败!返回err }回调(null,数据);//成功!以数组形式返回查询的结果});});});};新闻。射流研究…
复制代码代码如下:DOCTYPE html html head title %=title %/title link rel=' style sheets ' href='/style sheets/style。CSS/head body h1 %=title %/h1 ul % for(var k in data){ % Li div标题:%=数据k .标题%/分区内容:%=数据k .内容%/div附件:img src=' http : news/%=data[k].pic % '//div/div a href='/delete?id=%=数据' k] % '删除/a /div hr//li %} % /ul/body/html
结语
好了,文章发布系统的制作就先到这里了,以后我们再慢慢增加功能,慢慢做美化。