Express+EJS實現一個新聞列表頁面的新增和檢視
阿新 • • 發佈:2018-12-18
1、模組化思路
服務模組:負責啟動服務
路由模組:負責路由判斷
業務模組:負責處理具體路由的業務程式碼
資料操作模組:負責進行資料庫操作
配置模組:負責各個模組中用到的配置資訊
2、專案目錄
新建專案資料夾,安裝express和EJS
3、配置模組
config.js
// 配置模組: const path = require('path'); module.exports = { port: 8080, dataPath: path.join(__dirname, 'data', 'data.json'), viewPath: path.join(__dirname, 'views') };
4、方法模組:封裝一些重複利用的方法
method.js
// 封裝一些方法 const fs = require('fs'); const path = require('path'); const querystring = require('querystring'); const config = require('./config.js'); // 封裝讀取data.json檔案的方法 module.exports.readData = function (callback) { fs.readFile(config.dataPath, 'utf8', (err, data) => { if (err && err.code !== 'ENOENT') throw err; // 將讀取到的字串資料轉換成JSON物件 var list = JSON.parse(data || '[]'); // 通過呼叫回撥函式,將讀取到的資料list傳遞出去 callback(list); }) } // 封裝寫入data.json檔案的方法 module.exports.writeData = function (data, callback) { fs.writeFile(config.dataPath, data, err => { if(err) throw err; callback(); }) } // 封裝獲取使用者post提交的資料的方法 module.exports.getPostData = function (req, callback) { // 宣告一個數組,用來儲存使用者每次提交過來的資料 var array = []; req.on('data', chunk => { // 此處的chunk引數,就是瀏覽器本次提交過來的一部分資料 // chunk 的資料型別是Buffer (chunk就是一個Buffer物件) array.push(chunk); }); req.on('end', function () { // 把 array 中的所有資料彙總起來,然後把array中的Buffer物件集合起來,轉換成一個Buffer物件 // Buffer.concat方法將一組Buffer物件合併為一個Buffer物件。 var postData = Buffer.concat(array); // 將獲得的Buffer物件轉換成一個字串 postData = postData.toString('utf8'); // 將post請求的查詢字串,轉換成一個JSON物件,用到node.js中的 querystring 模組 postData = querystring.parse(postData); callback(postData); }); }
5、業務模組
handler.js
// 業務模組 const method = require('./method.js'); const path = require('path'); const config = require('./config.js'); module.exports.index = function (req, res) { method.readData(list => { // res.render()方法,預設是不能使用的,需要為express配置一個模板引擎,才能使用res.render() // 在app.js中設定了HTML模板所在路徑和要使用的模板引擎,在這裡就可以直接使用res.render()了 // 第一個引數:HTML模板檔名,第二個引數:要傳入HTML模板檔案的資料,第三個引數:回撥函式 res.render('index', {list: list}, (err, html) => { if(err) throw err; console.log('ok'); res.send(html); }); }); }; module.exports.submit = function (req, res) { res.sendFile(path.join(config.viewPath, 'submit.html'), err => { if(err) throw err; console.log('ok'); }); }; module.exports.detail = function (req, res) { // 1、獲取當前使用者請求的新聞的id console.log(req.query.id); // 2、讀取data.json檔案中的資料,根據id找到對應的新聞資料 method.readData(list => { var model = null; for(var i = 0; i < list.length; i++) { if(list[i].id.toString() === req.query.id) { model = list[i]; break; } } if(model) { // 3、呼叫res.render()函式進行模板引擎的渲染 res.render('detail', {item: model}, (err, html) => { if(err) throw err; console.log('ok detail'); res.send(html); }); } else { res.status(404).send('404, Not Found! 頁面不存在'); } }); }; module.exports.getAdd = function (req, res) { method.readData(list => { // 儲存新聞資料時增加一個id屬性 req.query.id = list.length; list.push(req.query); method.writeData(JSON.stringify(list), function () { console.log('ok'); res.redirect('/'); }); }); }; module.exports.postAdd = function (req, res) { method.readData(list => { method.getPostData(req, postData => { // 儲存新聞資料時增加一個id屬性 postData.id = list.length; list.push(postData); method.writeData(JSON.stringify(list), function () { console.log('post ok'); // 重定向到新聞列表頁面 res.redirect('/'); }); }); }); };
6、路由模組
router.js
// 路由模組:負責路由判斷
// 1、建立一個路由物件 router (router即是一個物件,也是一個函式)
const express = require('express');
const path = require('path');
const router = express.Router();
// 載入業務模組
const handler = require('./handler.js');
// 2、把所有路由都掛載到router上
// router.get('/', (req, res) => {
// handler.index(req, res);
// });
// 等價於
router.get('/', handler.index);
router.get('/index', handler.index);
router.get('/submit', handler.submit);
router.get('/detail', handler.detail);
router.get('/add', handler.getAdd);
router.post('/add', handler.postAdd);
// 對resources資料夾下的內容進行靜態資源託管
router.use('/resources', express.static(path.join(__dirname, 'resources')));
// 3、返回router物件
module.exports = router;
7、服務模組
app.js
// 入口檔案
// 服務模組:負責啟動服務
// 1、載入express模組
const express = require('express');
// 2、建立app物件
const app = express();
const ejs = require('ejs');
const path =require('path');
// 載入配置模組
const config = require('./config.js');
// 載入路由模組
const router = require('./router.js');
// 模板所在路徑
app.set('views', config.viewPath);
// 設定要用的模板引擎
app.set('view engine', 'ejs');
// 3、註冊路由
// 設定app與router相關聯
// app.use第一個引數不傳,預設為'/'
app.use(router);
// 4、啟動服務
app.listen(config.port, () => {
console.log(`http://localhost:${config.port}`);
});
8、三個HTML頁面程式碼
index.ejs
<ul>
<% for(var i = 0; i < list.length; i++) { %>
<li>
<span><%= list[i].id+1 %>.</span>
<a href="/detail?id=<%= list[i].id %>"><%= list[i].title %></a>
</li>
<% } %>
</ul>
detail.ejs
<h1><%= item.title %></h1>
<p><%= item.text %></p>
submit.html
<form method="post" action="/add">
<table>
<tr>
<td>title:</td>
<td><input type="text" name="title" value="" size="50"/></td>
</tr>
<tr>
<td>text:</td>
<td><textarea name="text" id="" cols="50" rows="4"></textarea></td>
</tr>
<tr>
<td><input type="submit" value="提交"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>