前言
我們今天就來做一個簡單的新聞發布系統,系統第一階段不需要太難,主要有以下功能
① 新聞類型管理
② 新聞管理(附圖片上傳功能)
③ 新聞瀏覽
功能雖然不多,但是也涵蓋很多基本操作了,程式不過增刪查改嘛,外加上傳附件,夠了。於是開始我們今天的學習
準備工作
根據昨天的折騰後,我們已經有了nodeJS與mongoDB環境了,現在直接新建工程文件與資料庫檔案即可
第一步,開啟命令符號切換到D碟後輸入
D:>express -e news
於是系統會自動開開心心建構基本環境
很明顯,裡面很多模組依賴沒有,這時候將昨天的package.json直接考過來:
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.4.8",
"ejs": "*",
"mongodb": "*"
}
}
然後切換到專案目錄下:
nmp install
依賴檔案全部搞下來了,然後我們輸入
D:news>node app
Express server listening on port 3000
於是,我們的程式高高興興的運作起來了,打開網址一看,確實沒問題
PS:這裡有個問題要注意,我們下載下來的檔案不是UTF-8編碼,所以中文可能有亂碼,檔案編碼需要各位自己統一
程式跑起來了就需要資料庫相關的配置了
① 先在mongoDB目錄中新建news資料夾
② 為專案新增設定檔settings.js
module.exports = {
cookieSecret: 'myNews',
db: 'news',
host: 'localhost'
};
③ 新建models目錄,新建db.js
var settings = require('../settings'),
Db = require('mongodb').Db,
Connection = require('mongodb').Connection,
Server = require('mongodb').Server;
module.exports = new Db(settings.db, new Server(settings.host, Connection.DEFAULT_PORT), { safe: true });
④ 在桌面新建news.bat程式
d:mongodbbinmongod.exedbpathpath:
d:mongodbbinmongod.exedbpathpath: >
以後要啟動資料庫,只需要運行他即可,如此,我們初步的準備工作基本結束
但這裡有兩個比較煩的事情,一個是每次要啟動news程式很煩,二個是修改任何東西都需要重啟,於是我們這裡先解決這兩個問題
① 在桌面新建news_app.bat,以後運行他就可以啟動程式了
node d:newsapp
② supervisor為一進程保護程序,我們可以使用他幫我們重啟程序,首先按照,然後調整我們的node_app.bat
supervisor d:newsapp
當然之前要安裝:
npm install -g supervisor
這個樣子後,修改了檔案就不需要手動重啟了(需要將news_app放到專案目錄下),於是準備工作到此為止
專案結構
第一步結束後,我們就需要思考下專案結構了
① 首頁為index這裡將列出所有新聞類型以及對於新聞條目
② 各新聞條目擁有編輯/刪除/查看 三個按鈕
③ 首頁有增加新聞按鈕(增加時候可上傳圖片)
基本功能如上
於是,我們去掉app裡面的路由功能,將路由全部放到index裡面
程式碼如下:
//將路由功能放入index
//app.get('/', routes.index);
//app.get('/users', user.list);
routes(app);
程式碼如下:
module.exports = function (app) {
//首頁,現在也是首頁
app.get('/', function (req, res) {
res.render('index', { title: 'Express' });
});
app.get('/add', function (req, res) {
res.send('增加新聞請求');
});
app.get('/delete', function (req, res) {
res.send('刪除新聞請求');
});
app.get('/view', function (req, res) {
res.send('查看新聞請求');
});
app.get('/update', function (req, res) {
res.send('修改新聞請求');
});
};
第一步簡單如此,因為增加新聞應該有單獨的頁面,而具體點擊增加按鈕又會有其他處理,所以內部還得細分各個請求,現在規定如下:
/ 預設頁面,該頁面顯示所有類型以及新聞,並帶有刪除按鈕
/add 進入新增新聞頁面
/addNews 新增新聞具體post請求地址(點擊按鈕時候的回應)
/delete 刪除新聞請求
/view 具體新聞查詢
於是稍微修改下上述路由:
程式碼如下:
module.exports = function (app) {
//首頁,現在也是首頁
app.get('/', function (req, res) {
res.render('index', { title: 'Express' });
});
app.get('/add', function (req, res) {
res.send('新增新聞頁');
});
app.post('/addNews', function (req, res) {
res.send('處理新增新聞請求');
});
app.get('/delete', function (req, res) {
res.send('刪除新聞請求');
});
app.get('/view', function (req, res) {
res.send('查看新聞請求');
});
};
於是我們需要新建幾個模板來組織我們的網頁,這裡我們先不分離頭尾只要最簡單的頁面即可
新增add與view兩個範本文件,暫時表現與index.ejs一致,並且修改導航相關
程式碼如下:
module.exports = function (app) {
//首頁,現在也是首頁
app.get('/', function (req, res) {
res.render('index', { title: 'Express' });
});
app.get('/add', function (req, res) {
res.render('add', { title: '新增新聞頁面' });
});
app.post('/addNews', function (req, res) {
res.send('處理新增新聞請求');
});
app.get('/delete', function (req, res) {
res.send('刪除新聞請求');
});
app.get('/view', function (req, res) {
res.render('view', { title: '查看新聞請求' });
});
};
至此項目結構結束
資料操作
整體結構出來後,我們就需要進行資料操作了:
① 增加資料(增加新聞)
② 展示數據(展示新聞)
③ 刪除資料(刪除新聞)
本來還涉及到類型操作的,但是做著做著給搞沒了,暫時不管他吧,因為首次做容易迷糊
增加新聞
這裡,我們就不使用表單提交了,我們用ajax......這裡順便引入zepto庫,於是我們的頁面成了這樣
雖然現在還沒有要求回應程序,所以資料並不會被處理,另外我們這裡的附件也沒有(現在附件只允許一個好了),於是再修改下程式碼,加入圖片:
PS:比較麻煩的是圖片經過ajax處理有點麻煩,所以我們這裡乖乖的換回form操作算了,不然又要搞多久......
這個樣子就需要過多的考慮附件問題,先暫時如此吧,現在先處理請求程序,這裡先在public裡面新建news文件夾用於存儲其圖片
模特兒
在models資料夾中新增news.js文件,用於建立實體,並提供新增查詢相關操作:
var mongodb = require('./db');
函數新聞(標題、內容、圖片){
this.title = 標題;
this.content = 內容;
this.pic = pic;//儲存儲存路徑
};
module.exports = 新聞;
// 儲存資料
News.prototype = {
儲存:函數(回呼){
var date = new Date();
var 時間 = {
日期:日期,
年:date.getFullYear(),
月份: date.getFullYear() "-" (date.getMonth() 1),
日: date.getFullYear() "-" (date.getMonth() 1) "-" date.getDate(),
分鐘: date.getFullYear() "-" (date.getMonth() 1) "-" date.getDate() " "
date.getHours() ":" (date.getMinutes()
}
//資料儲存物件
var 新聞 = {
標題: this.title,
內容:this.content,
pic: this.pic, //圖片處理最後來說,現在先亂存
時間:時間
};
//開啟資料連接,開啟就是一個回呼......
mongodb.open(函數(err, db) {
//錯誤就退出
如果(錯誤){
返回回呼(錯誤);
}
//打開新聞集合
db.collection('新聞', function (err, collection) {
若(錯誤){
mongodb.close();
返回回呼(錯誤);
}
// 讀取集合(讀取資料庫)
collection.insert(news, { safe: true }, function (err) {
返回回呼(錯誤);
});
callback(null);//err為null
});
});
}
};
於是,寫入資料庫的程式就有了,這裡我們來試試能不能插入資料庫,當然需要修改路由處的程式
PS:路由處當然不能寫過多邏輯程式碼,這個檔案以後還要分離
這時候/addNews裡面的邏輯需要改變
app.post('/addNews', function (req, res) {
var title = req.body.title;
var content = req.body.content;
var pic = req.body.pic;
var news = new News(title, content, pic)
news.save(function (err, data) {
res.send(data);
})
});
查詢下,問題不大,現在要解決的就是附件問題了
上傳圖片
上傳圖片功能express本身就支援了,express透過bodyParser解析請求體,然後便可透過他上傳文件了,其內部使用了formidable
這裡將app.js裡面的app.use(express.bodyParser())改為:
app.use(express.bodyParser({ keeptensions: :Extensions: true './public/news' }));
開啟index.js,在前面加一行程式碼:
fs = require('fs'),
fs = require('fs'),
修改一下index檔:
複製程式碼
程式碼如下:
app.post('/addNews', function (req, res) {
for (var i in req.files) {
if (req.files[i] == 0) {
//同步方式刪除一個檔案
fs.unlinkSync(req.files[i].path);
console.log('success removed an empty file');
} else {
var path = './public/news/' req.files[i].name;
// 使用同步方式重新命名一個檔案
fs.renameSync(req.files[i].path, path);
console.log('sunccess renamed a file');
}
}
// var title = req.body.title;
// var content = req.body.content;
// var pic = req.body.pic;
// var news = new News(title, content, pic)
// news.save(function (err, data) {
// res.send(data);
// })
});
這個時候選取文件後點選新增新聞,我們的文件就上傳上去了
這時候,我只需要將檔名記錄在資料庫即可,檔案目錄裡面就有圖片了
複製程式碼
程式碼如下:
app.post('/addNews', function (req, res) {
var pic = null;
for (var i in req.files) {
if (req.files[i] == 0) {
//同步方式刪除一個檔案
fs.unlinkSync(req.files[i].path);
console.log('success removed an empty file');
} else {
var path = './public/news/' req.files[i].name;
// 使用同步方式重新命名一個檔案
fs.renameSync(req.files[i].path, path);
console.log('sunccess renamed a file');
}
pic = req.files[i].name;
}
var title = req.body.title;
var content = req.body.content;
var news = new News(title, content, pic)
news.save(function (err, data) {
res.send(data);
})
res.send('
請求成功,回首頁 ');
});
資料庫中有資料了,我們目錄也有文件了,現在只需要將資料讀出來了
PS:放假兄弟們催的兇,要出去喝酒了
讀取資料
第二步當然是讀取數據,首先是首頁的數據讀取:
var mongodb = require('./db');
function News(title, content, pic) {
this.title = title;
this.content = content;
this.pic = pic;//儲存儲存路徑
};
module.exports = News;
//儲存資料
News.prototype = {
save: function (callback) {
var date = new Date();
//資料儲存物件
var news = {
title: this.title,
content: this.content,
pic: this.pic, //圖片處理最後來說,現在先亂存
date: date
};
//開啟資料連接,開啟就是一個回呼......
mongodb.open(function (err, db) {
//錯誤就退出
if (err) {
return callback(err);
}
//開啟news集合
db.collection('news', function (err, collection) {
if (err) {
mongodb.close();
return callback(err);
}
//寫入集合(寫入資料庫)
collection.insert(news, { safe: true }, function (err) {
return callback(err);
});
callback(null); //err為null
});
});
}
};
//讀取文章及其相關資訊
News.get = function (id, callback) {
//開啟資料庫
mongodb.open(function (err, db) {
if (err) {
return callback(err);
}
db.collection('news', function (err, collection) {
if (err) {
mongodb.close();
return callback(err);
}
var query = {};
if (id) {
query.id = id;
}
//依據 query 物件查詢文章
collection.find(query).sort({
date: -1
}).toArray(function (err, data) {
mongodb.close();
if (err) {
return callback(err); //失敗!返回 err
}
callback(null, data); //成功!以數組形式傳回查詢的結果
});
});
});
};
news.js
標題>
頭>
標題:
內容:
附件:
身體>
結語
好了,文章發佈系統的製作就先到這裡了,以後我們再慢慢增加功能,慢慢做美化。