後端使用node寫的一個一整套的博客系統javascript
#### 主要功能css
nodehtml
html css js ajax等前端
indexjava
詳情頁node
後臺git
├─models 存放數據庫數據模型
├─public 存放靜態資源
├─routers 路由文件
├─schemas 數據庫Schema表
└─views 靜態頁面github
│ .gitignore github倉庫上傳忽略文件
│ app.js 主程序入口文件
│ package-lock.json
│ package.json
│ README.mdajax
使用npm安裝項目要使用的包sql
var express = require('express') var mongoose = require('mongoose') var app = express() // 鏈接數據庫 mongoose.connect('mongodb://localhost/node-blog', { useNewUrlParser: true }); app.listen(3000, function () { console.log('http://localhost:3000') })
// 定義模板引擎 app.engine('html', swig.renderFile) // 設置模板文件存放目錄 app.set('views', './views') // 註冊模板引擎 app.set('view engine', 'html') //設置swig頁面不緩存 swig.setDefaults({ allowErrors: false, autoescape: true, cache: false })
// 靜態文件託管 app.use('/public', express.static(__dirname + '/public')
知識點1:在 Express 中提供靜態文件
爲了提供諸如圖像、CSS 文件和 JavaScript 文件之類的靜態文件,請使用 Express 中的
express.static
內置中間件函數。
app.use(express.static('public'));
這樣後 咱們就能夠訪問public文件中的任意目錄的任意文件:
http://localhost:3000/images/kitten.jpg http://localhost:3000/css/style.css http://localhost:3000/js/app.js
注意: Express 相對於靜態目錄查找文件,所以靜態目錄的名稱不是此 URL 的一部分。
能夠屢次使用static函數開啓多個靜態資源入口。
自定義文件目錄名稱
上面的例子中咱們能夠訪問 http://localhost:3000/js/app.js
這個目錄 可是若是我想經過http://localhost:3000/static/js/app.js
來訪問,咱們可使用:
app.use('/static', express.static('public'));
來建立虛擬路徑前綴(路徑並不實際存在於文件系統中)
固然,在項目中通常使用絕對路徑來保證代碼的可行性:
app.use('/static', express.static(__dirname + '/public'));
// 鏈接數據庫 mongoose.connect('mongodb://localhost/node-blog' { useNewUrlParser: true });
mongod會在第一個數據建立的時候新建咱們的node-blog數據庫,不須要咱們手動建立
後面的一個配置項最好加上。不報錯的話可不加。
// 路由 app.use('/admin', require('./routers/admin')) app.use('/api', require('./routers/api')) app.use('/', require('./routers/main'))
知識點2:express.Router的使用
使用
express.Router
類來建立可安裝的模塊化路由處理程序。Router
實例是完整的中間件和路由系統;所以,經常將其稱爲「微型應用程序」。
使用express.Router,能夠將路由更加模塊化
好比:在 routers文件夾下新建 main.js
var express = require('express') var router = express.Router() ... router.get('/', function (req, res, next) { ... } router.get('/view',(req, res) => { ... } module.exports = router
末尾使用module.exports = router 將router對象暴露出去
咱們將其安裝在主應用程序app.js的路徑中
... app.use('/', require('./routers/main')) ...
此時的 ‘/’ 路徑請求的就是 main.js中的 ’/‘
/view --> main.js 中的 '/view'
功能模塊開發順序
編碼順序
新建並編寫 schemas/user.js
var mongoose = require('mongoose') // 用戶表結構 module.exports = new mongoose.Schema({ username: { type: String }, password: { type: String } })
var mongoose = require('mongoose') var userSchema = require('../schemas/user') module.exports = mongoose.model('User', userSchema)
知識點3:mongoose中的 Schema 和 Model
Mongoose 的一切始於 Schema。每一個 schema 都會映射到一個 MongoDB collection ,並定義這個collection裏的文檔的構成
定義一個schema
var mongoose = require('mongoose'); var Schema = mongoose.Schema; var blogSchema = new Schema({ title: String, author: String, body: String, comments: [{ body: String, date: Date }], date: { type: Date, default: Date.now }, hidden: Boolean, meta: { votes: Number, favs: Number } });
建立一個model
咱們要把 schema 轉換爲一個 Model, 使用
mongoose.model(modelName, schema)
函數:
var Blog = mongoose.model('Blog', blogSchema);
Models 是從 Schema
編譯來的構造函數。 它們的實例就表明着能夠從數據庫保存和讀取的 documents。 從數據庫建立和讀取 document 的全部操做都是經過 model 進行的。
第一個參數是跟 model 對應的集合( collection )名字的 單數 形式。 Mongoose 會自動找到名稱是 model 名字 複數形式的 collection 。 對於上例,Blog這個 model 就對應數據庫中 blogs 這個 collection。.model()
這個函數是對 schema
作了拷貝(生成了 model)。
你要確保在調用
.model()
以前把全部須要的東西都加進schema
裏了
一個model就是創造了一個mongoose實例,咱們才能將其操控。
個人片面理解把Schema和model的關係 想成 構造函數和實例之間的關係
註冊邏輯
靜態頁面
處理 前端ajax註冊
// 註冊 $register.find('.user_register_btn').on('click', function () { $.ajax({ type: 'post', url: 'api/user/register', data: { username: $register.find('[name="username"]').val(), password: $register.find('[name="password"]').val(), repassword: $register.find('[name="repassword"]').val() }, dataType: 'json', success: function (result) { $register.find('.user_err').html(result.message) if (!result.code) { setTimeout(() => { $('.j_userTab span')[0].click() }, 1000) } } }) })
後臺api路由
在api.js中編寫後臺註冊相關代碼
/* 註冊: 註冊邏輯 1. 用戶名不能爲空 2. 密碼不能爲空 3. 兩次密碼一致 數據庫查詢 1. 用戶名是否已經被註冊 */ router.post('/user/register', function (req, res, next) { var username = req.body.username var password = req.body.password var repassword = req.body.repassword // -------表單簡單驗證----------- if (username == '') { responseData.code = 1 responseData.message = '不填用戶名啊你' res.json(responseData) return } if (password == '') { responseData.code = 2 responseData.message = '密碼不填?' res.json(responseData) return } if (password !== repassword ) { responseData.code = 3 responseData.message = '兩次密碼不一致啊' res.json(responseData) return } // ------------------------------- // -------數據庫驗證驗證----------- User.findOne({ username: username }).then((userInfo) => { if (userInfo) { // 數據庫中已有用戶 responseData.code = 4 responseData.message = '用戶名有了,去換一個' res.json(responseData) return } // 保存用戶註冊信息 var user = new User({ username: username, password: password }) return user.save() }).then((newUserInfo) => { responseData.message = '耶~ 註冊成功' res.json(responseData) }) // ------------------------------- })
後臺經過簡單的驗證,將結果經過 res.json
的方式來返還給 前臺 ajax 再經過json信息來處理頁面展現。
知識點4:使用body-parser
中間件來處理post請求
使用案例
var express = require('express') var bodyParser = require('body-parser') var app = express() // parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })) // parse application/json app.use(bodyParser.json())
經過以上的配置,咱們就能夠獲取經過 req.body 來獲取 post 請求總的參數了
... var username = req.body.username var password = req.body.password var repassword = req.body.repassword ...
知識點5: mongoose中數據庫的操做
前段時間總結過一些mongoose的增刪查操做筆記:
#### 3.4 登陸
前臺ajax
// 登陸 $login.find('.user_login_btn').on('click', function () { $.ajax({ type: 'post', url: 'api/user/login', data: { username: $login.find('[name="username"]').val(), password: $login.find('[name="password"]').val(), }, dataType: 'json', success: function (result) { $login.find('.user_err').html(result.message) // 登陸成功 if (!result.code) { window.location.reload() } } }) })
後臺路由處理及數據庫查詢
// 登陸邏輯處理 router.post('/user/login', (req, res) => { var username = req.body.username var password = req.body.password if (username == '' || password == '') { responseData.code = 1 responseData.message = '去填完再點登陸' res.json(responseData) return } // 查詢數據庫用戶名密碼同時存在 User.findOne({ username: username, password: password }).then((userInfo) => { if (!userInfo) { responseData.code = 2 responseData.message = '用戶名或密碼錯啦' res.json(responseData) return } // 正確 登陸成功 responseData.message = '耶~ 登陸成功' responseData.userInfo = { _id: userInfo._id, username: userInfo.username } req.cookies.set('userInfo', JSON.stringify({ _id: userInfo._id, username: escape(userInfo.username) })) res.json(responseData) }) })
上面的案例中,爲了記錄咱們的登陸狀態,咱們使用了第三發包 -- cookies 來存儲登陸信息
app 引入 cookies模塊
var Cookies = require('cookies')
在 api.js 中獲取 cookies
req.cookies.set('userInfo', JSON.stringify({ _id: userInfo._id, username: escape(userInfo.username) }))
在 app.js 中解析登陸用戶的cookies
// 設置cookies app.use((req, res, next) => { req.cookies = new Cookies(req, res) // 解析登陸用戶的cookies req.userInfo = {} if (req.cookies.get('userInfo')) { try { req.userInfo = JSON.parse(req.cookies.get('userInfo')) // 獲取用戶是不是管理員 User.findById(req.userInfo._id).then((userInfo) => { req.userInfo.isAdmin = Boolean(userInfo.isAdmin) next() }) } catch (e) { next() } } else { next() } }
用 swig 渲染模板控制 index頁面
ajax --》 api.js --> cookies設置爲空 -> 刷新頁面
登出的實現就比較簡單,只需將cookies設置爲空便可
前臺ajax
// 登出 $('#logout').on('click', function () { $.ajax({ url: '/api/user/logout', success: function(result) { if (!result.code) { window.location.reload() } } }) })
api路由
// 退出登陸 router.get('/user/logout', (req, res) => { req.cookies.set('userInfo', null) res.json(responseData) })
緣由 cookies在存儲中午時出現亂碼
解決辦法 將username進行轉碼再解碼
使用 encode
和 decode
來進 編碼和解碼
給userInfo 添加 isAdmin 屬性
使用swig 選擇渲染
公用的繼承
{% extends 'layout.html' %}
特殊的重寫
{% block main %} <div class="jumbotron"> <h1>Hello, {{userInfo.username}}!</h1> <p>歡迎進入後臺管理</p> </div> {% endblock%}
admin 首頁
// 首頁 router.get('/', (req, res, next) => { res.render('admin/index', { userInfo: req.userInfo }) })
創建靜態 user_index.html
處理路由及分頁邏輯
// 用戶管理 router.get('/user', (req, res) => { /* 從數據庫中讀取全部的用戶數據 limit(number) 限制獲取的數據條數 skip(number) 忽略數據的條數 每頁顯示 5 條 第一頁: 1-5 skip:0 -> (當前頁 1 - 1) * 每頁的條數 第二頁: 6-10 skip:5 -> (當前頁 2 - 1) * 每頁的條數 ... ... User.count() 查詢總數據量 */ var page = Number(req.query.page || 1) var pages = 0 var limit = 10 User.count().then((count) => { // 計算總頁數 pages = Math.ceil(count / limit) // 取值不能超過 pages page = Math.min(page, pages) // 取值不能小於1 page = Math.max(page, 1) var skip = (page - 1) * limit // 讀取數據庫中全部用戶數據 User.find().limit(limit).skip(skip).then((users) => { res.render('admin/user_index', { userInfo: req.userInfo, users: users, page: page, pages: pages, count: count, limit: limit }) }) }) })
頁面展現 --table表格
分頁
數據裏 limit
skip()
分頁原理
/* 從數據庫中讀取全部的用戶數據 limit(number) 限制獲取的數據條數 skip(number) 忽略數據的條數 每頁顯示 5 條 第一頁: 1-5 skip:0 -> (當前頁 1 - 1) * 每頁的條數 第二頁: 6-10 skip:5 -> (當前頁 2 - 1) * 每頁的條數 ... ... */ var page = req.query.page || 1 var limit = 5 var skip = (page - 1) * limit User.find().limit(limit).skip(skip).then((users) => { res.render('admin/user_index', { userInfo: req.userInfo, users: users }) })
客戶端實現
<nav aria-label="..."> <ul class="pager"> <li class="previous"><a href="/admin/user?page={{page-1}}"><span aria-hidden="true">←</span>上一頁</a></li> <li> 一共有 {{count}} 條數據 || 每頁顯示 {{limit}} 條數據 || 一共 {{pages}} 頁 || 當前第 {{page}} 頁 </li> <li class="next"><a href="/admin/user?page={{page+1}}">下一頁<span aria-hidden="true">→</span></a></li> </ul> </nav>
服務端代碼
/* 從數據庫中讀取全部的用戶數據 limit(number) 限制獲取的數據條數 skip(number) 忽略數據的條數 每頁顯示 5 條 第一頁: 1-5 skip:0 -> (當前頁 1 - 1) * 每頁的條數 第二頁: 6-10 skip:5 -> (當前頁 2 - 1) * 每頁的條數 ... ... User.count() 查詢總數據量 */ var page = Number(req.query.page || 1) var pages = 0 var limit = 5 User.count().then((count) => { // 計算總頁數 pages = Math.ceil(count / limit) // 取值不能超過 pages page = Math.min(page, pages) // 取值不能小於1 page = Math.max(page, 1) var skip = (page - 1) * limit User.find().limit(limit).skip(skip).then((users) => { res.render('admin/user_index', { userInfo: req.userInfo, users: users, page: page, pages: pages, count: count, limit: limit }) }) })
抽取page 使用 include 語法之後複用
分類首頁
category_index.html
添加分類
category_add.html
get 渲染頁面
post 提交頁面
設計表結構
schemas/categories.js
models/categories.js
相關代碼
/* 添加分類頁面 */ router.get('/category/add', (req, res) => { res.render('admin/category_add', { userInfo: req.userInfo }) }) /* 添加分類的保存 */ router.post('/category/add', (req, res) => { var name = req.body.name || '' if (name == '') { res.render('admin/error', { userInfo: req.userInfo, message: '名稱不能爲空' }) return } // 是否已有分類 Category.findOne({ name: name }).then((result) => { if (result) { // 數據庫中已經存在 res.render('admin/error', { userInfo: req.userInfo, message: '分類已經存在' }) return Promise.reject() } else { // 數據庫中不存在分類 return new Category({ name: name }).save() } }).then((newCategory) => { res.render('admin/success', { userInfo: req.userInfo, message: '分類保存成功', url: '/admin/category' }) }) })
經過判斷 渲染 error 或者 success 的頁面 兩個頁面都在 admin/error.html
和 admin/success.html
中
首頁展現展現
同用戶管理首頁展現同樣
/* 分類首頁 */ router.get('/category', (req, res) => { var page = Number(req.query.page || 1) var pages = 0 var limit = 10 Category.count().then((count) => { // 計算總頁數 pages = Math.ceil(count / limit) // 取值不能超過 pages page = Math.min(page, pages) // 取值不能小於1 page = Math.max(page, 1) var skip = (page - 1) * limit Category.find().limit(limit).skip(skip).then((categories) => { res.render('admin/category_index', { userInfo: req.userInfo, categories: categories, page: page, pages: pages, count: count, limit: limit }) }) }) })
分類修改 刪除
在渲染的分類首頁的分類表格中加入
<td> <a href="/admin/category/edit?id={{category._id.toString()}}" class="btn btn btn-primary">修改</a> <a href="/admin/category/delete?id={{category._id.toString()}}" class="btn btn-danger">刪除</a> </td>
經過query的傳值分類的id 值 咱們來操做id
修改
get
/* 分類修改 get */ router.get('/category/edit', (req, res) => { // 獲取要修改的分類信息 表單形式展示出來 var id = req.query.id || '' // 獲取修改的分類信息 Category.findById(id).then((category) => { if (!category) { res.render('admin/error', { userInfo: req.userInfo, message: '分類信息不存在' }) return Promise.reject() } else { res.render('admin/category_edit', { userInfo: req.userInfo, category: category }) } }) })
post
/* 分類修改 post */ router.post('/category/edit', (req, res) => { var id = req.query.id || '' var name = req.body.name || '' Category.findById(id).then((category) => { if (!category) { res.render('admin/error', { userInfo: req.userInfo, message: '分類信息不存在' }) return Promise.reject() } else { // 當前用戶沒有作任何修改而提交 if (name == category.name) { res.render('admin/success', { userInfo: req.userInfo, message: '修改爲功', url: '/admin/category' }) return Promise.reject() } else { // 要修改的分類名稱是否已經在數據庫中 return Category.findOne({ // id 不等於當前的id _id: {$ne: id}, name: name }) } } }).then((sameCategory) => { if (sameCategory) { res.render('admin/error', { userInfo: req.userInfo, message: '已存在同名分類' }) return Promise.reject() } else { return Category.findByIdAndUpdate(id, { name: name }) } }).then(() => { res.render('admin/success', { userInfo: req.userInfo, message: '修改分類名稱成功', url: '/admin/category' }) }) })
刪除
/* 分類刪除 */ router.get('/category/delete', (req, res) => { // 獲取id var id = req.query.id || '' Category.remove({ _id: id }).then(() => { res.render('admin/success', { userInfo: req.userInfo, message: '刪除成功', url: '/admin/category' }) }) })
/* 內容首頁 */ router.get('/content', (req, res) => { res.render('admin/content_index', { userInfo: req.userInfo }) }) /* 內容添加 */ router.get('/content/add', (req, res) => { Category.find().sort({_id: -1}).then((categories) => { console.log(categories) res.render('admin/content_add', { userInfo: req.userInfo, categories: categories }) }) })
新建 schemas/content.js 和 models/content.js 創建content模型
處理路由
post
後臺
// 保存內容到數據庫 new Content({ category: req.body.category, title: req.body.title, description: req.body.description, content: req.body.content }).save().then((content) => { res.render('admin/success', { userInfo: req.userInfo, message: '內容保存成功', url: '/admin/content' }) }) })
module.exports = new mongoose.Schema({ title: { type: String }, // 引用 關聯字段 category: { type: mongoose.Schema.Types.ObjectId, //引用 另一張表的模型 ref: 'Category' }, description: { type: String, default: '' }, content: { type: String, default: '' } })
咱們在 處理 content 的 category的時候 關聯個 另一個結構表
在渲染頁面的時候用mongoose 中提供搞得 populate() 方法
知識點6: mongoose中的表關聯
Population 能夠自動替換 document 中的指定字段,替換內容從其餘 collection 獲取。 咱們能夠填充(populate)單個或多個 document、單個或多個純對象,甚至是 query 返回的一切對象
簡單的說,A表的能夠關聯B表,經過調用A表的屬性數據取到B表內容的值,就像sql的join的聚合操做同樣。
var mongoose = require('mongoose'); var Schema = mongoose.Schema; var personSchema = Schema({ _id: Schema.Types.ObjectId, name: String, age: Number, stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }] }); var storySchema = Schema({ author: { type: Schema.Types.ObjectId, ref: 'Person' }, title: String, fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }] }); var Story = mongoose.model('Story', storySchema); var Person = mongoose.model('Person', personSchema);
咱們建立了Story 和 Person兩個數據庫實例。
Person
model 的 stories
字段設爲 ObjectId
數組。 ref
選項告訴 Mongoose 在填充的時候使用哪一個 model,本例中爲 Story
model。
接下來咱們使用 Population 來填充使用
Story. findOne({ title: 'Casino Royale' }). populate('author'). exec(function (err, story) { if (err) return handleError(err); console.log('The author is %s', story.author.name); // prints "The author is Ian Fleming" });
更多高級用法: Mongoose Populate
/* 修改內容 */ router.get('/content/edit', (req, res) => { // 獲取要修改的內容信息 表單形式展示出來 var id = req.query.id || '' var categories = [] // 獲取分類信息 Category.find().sort({ _id: -1 }) .then((result) => { categories = result return Content.findById(id).populate('category') }) .then((content) => { console.log(content) if (!content) { res.render('admin/error', { userInfo: req.userInfo, message: '指定內容不存在' }) return Promise.reject() } else { res.render('admin/content_edit', { userInfo: req.userInfo, content: content, categories: categories }) } })
/* 內容修改 */ router.post('/content/edit', function(req, res) { var id = req.query.id || '' if (req.body.title == '') { res.render('admin/error', { userInfo: req.userInfo, message: '標題不能爲空' }) return } if (req.body.description == '' || req.body.content == '') { res.render('admin/error', { userInfo: req.userInfo, message: '簡介和內容不能爲空' }) return } Content.findByIdAndUpdate(id, { category: req.body.category, title: req.body.title, description: req.body.description, content: req.body.content }).then(() => { res.render('admin/success', { userInfo: req.userInfo, message: '內容保存成功', url: '/admin/content' }) }) }) })
/* 內容刪除 */ router.get('/content/delete', (req, res) => { // 獲取id var id = req.query.id || '' Content.remove({ _id: id }).then(() => { res.render('admin/success', { userInfo: req.userInfo, message: '刪除成功', url: '/admin/content' }) }) })
做者 -- 關聯 user表
建立時間 -- new Date()
前臺渲染
<td>{{content.addTime|date('Y-m-d H:i:s', -8*60)}}</td>
點擊量 --》 先默認爲 0
有了後臺的數據,咱們接下來看前臺的
修改 main.js
/* 首頁渲染 */ router.get('/', function (req, res, next) { req.userInfo.username = unescape(req.userInfo.username) var data = { userInfo: req.userInfo, categories: [], contents: [], count: 0, page : Number(req.query.page || 1), pages : 0, limit : 10 } Category.find() .then((categories) => { data.categories = categories return Content.count() }) .then((count) => { data.count = count // 計算總頁數 data.pages = Math.ceil(data.count / data.limit) // 取值不能超過 pages data.page = Math.min(data.page, data.pages) // 取值不能小於1 data.page = Math.max(data.page, 1) var skip = (data.page - 1) * data.limit return Content .find() .sort({ addTime: -1 }) .limit(data.limit) .skip(skip) .populate(['category', 'user']) }) .then((contents) => { data.contents = contents console.log(data) res.render('main/index', data) }) })
使用swig的渲染模板 完善頁面信息,不在贅述
{% if pages > 1 %} <nav aria-label="..." id="pager_dh"> <ul class="pager"> {% if page <=1 %} <li class="previous"><span href="#"><span aria-hidden="true">←</span>沒有上一頁了</span></li> {%else%} <li class="previous"><a href="/?category={{category}}&page={{page-1}}"><span aria-hidden="true">←</span>上一頁</a></li> {%endif%} <span class="page_text">{{page}} / {{pages}}</span> {% if page >=pages %} <li class="next"><span href="#">沒有下一頁了<span aria-hidden="true">→</span></li> {%else%} <li class="next"><a href="/?category={{category}}&page={{page+1}}">下一頁<span aria-hidden="true">→</span></a></li> {%endif%} </ul> </nav> {%endif%}
咱們建立addTime的時候,會發現mongod建立的數據的時間戳徹底同樣
咱們不能使用new date()
來建立默認時間 使用 Date.now
var where = {} if (data.category) { where.category = data.category }
mongoose查詢的時候使用 where
查詢
<nav class="head_nav"> {% if category == ''%} <a href="/" id="inactive">首頁</a> {%else%} <a href="/">首頁</a> {%endif%} {% for cate in categories%} {% if category == cate.id%} <a href="/?category={{cate.id}}" id="inactive">{{cate.name}}</a> {%else%} <a href="/?category={{cate.id}}">{{cate.name}}</a> {%endif%} {% endfor %} </nav>
評論使用ajax來操做
使用ajax操做不刷新頁面來操做api
後臺api代碼
/* 進入詳情獲取評論 */ router.get('/comment/post', (req, res) => { var contentid = req.query.contentid Content.findById(contentid) .then((content) => { responseData.data = content.comments res.json(responseData) }) }) /* 評論提交 */ router.post('/comment/post', (req, res) => { var contentid = req.body.contentid var postData = { username: req.userInfo.username, postTime: Date.now(), content: req.body.content } // 查詢文章內容信息 Content.findById(contentid) .then((content) => { content.comments.push(postData) return content.save() }) .then((newContent) => { responseData.message = '評論成功!' responseData.data = newContent res.json(responseData) }) })
評論代碼
ajax的操做都封裝在了 routers/api.js 中
評論相關操做咱們都放在了js/comments.js 中
var limit = 4 var page = 1 var pages = 0 var comments = [] // 加載全部評論 $.ajax({ type: 'get', url: 'api/comment/post', data: { contentid: $('#contentId').val(), }, success: ((responseData) => { comments = responseData.data renderComment() }) }) $('.pager').delegate('a', 'click', function() { if ($(this).parent().hasClass('previous')) { page-- } else { page++ } renderComment() }) // 提交評論 $('#commentBtn').on('click',function() { $.ajax({ type: 'post', url: 'api/comment/post', data: { contentid: $('#contentId').val(), content: $('#commentContent').val() }, success: ((responseData) => { $('#commentContent').val('') comments = responseData.data.comments renderComment(true) }) }) }) function renderComment (toLaster) { $('#discuss_count').html(comments.length) var $lis = $('.pager li') pages = Math.ceil(comments.length / limit) if (!toLaster) { var start = (page-1) * limit } else { var start = (pages - 1) * limit page = pages } var end = (start + limit) > comments.length ? comments.length : (start + limit) if (pages <= 1) { $('.pager').hide() } else { $('.pager').show() $lis.eq(1).html(page + '/' + pages ) if (page <= 1) { page = 1 $lis.eq(0).html('<span>已經是最前一頁</span>') } else { $lis.eq(0).html('<a href="javacript:void(0);">上一頁</a>') } if (page >= pages) { page = pages $lis.eq(2).html('<span>已經是最後一頁</span>') } else { $lis.eq(2).html('<a href="javacript:void(0);">下一頁</a>') } } var html = '' if (comments.length) { for (var i = start; i < end; i++) { html += ` <li> <p class="discuss_user"><span>${comments[i].username}</span><i>發表於 ${formatDate(comments[i].postTime)}</i></p> <div class="discuss_userMain"> ${comments[i].content} </div> </li> ` } } $('.discuss_list').html(html) } function formatDate(d) { var date1 = new Date(d) return date1.getFullYear() + '年' + (date1.getMonth()+1) + '月' + date1.getDate() + '日' + date1.getHours() + ':' + date1.getMinutes() + ':' + date1.getSeconds() }
項目這個階段知識簡單能跑痛而已,包括細節的優化,和程序的安全性都沒有考慮,安全防範措施爲零,這也是之後要學習的地方。
第一次使用node寫後臺,完成了一次先後端的完整交互,最終要的仍是作後臺的一種思想,一種處理先後臺關係的邏輯。
收穫了不少,愈來愈感受本身要學的東西太多了,本身好菜。。
寫總結文檔有點累唉 _(°:з」∠)_禿頭。