本文檔根據慕課網視頻學習所總結css
- 建立一個項目目錄imooc
- 根目錄下建立app.js與views目錄 終端打開項目並輸入命令:
npm init
npm install express jade moment mongoose
- 新建app.js,編寫入口文件:
#app.js
var express =require('express')//加載express這個模塊
var port = process.env.PORT || 3000//設置端口:process是全局變量
var app = express()//啓動一個web服務器
app.set('views','./views')//設置視圖的根目錄
app.set('view engine','jade')//設置默認的模板引擎
app.listen(port)//監聽端口
console.log('imooc started on port ' + port)//打印一條日誌,控制檯查看服務是否能成功啓動
//添加路由
//index page
app.get('/index',function(req,res){//瀏覽器中訪問頁面是以get方法提交提交的,參數一位匹配規則,參數二爲回調方法
res.render('index',{
title:'imooc 首頁'
})
})
//detail page
app.get('/movie/:id',function(req,res){
res.render('detail',{
title:'detail 詳情頁'
})
})
//list page
app.get('/list',function(req,res){
res.render('list',{
title:'imooc 列表頁'
})
})
//admin page
app.get('/admin/movie',function(req,res){
res.render('admin',{
title:'imooc 後臺錄入頁'
})
})
複製代碼
項目結構爲: html
doctype html head meta(chaset="utf-8") title #{title} body h1 #{title}node
#將以上代碼直接copy在四個jade文件中且注意變換格式
#@將該項目在終端下打開並輸入 node app.js,檢測是否正確啓動(也能夠PORT=40000 node app.js 啓動)
#在瀏覽器的輸入地址:localhost:3000/index,localhost:3000/list,localhost:3000/admin/movie,localhost:3000/admin/01查看是否正確啓動。
複製代碼
修改目錄結構-運用jade語法能夠繼承的優勢以及公共區塊的調用 在views中新建includes文件夾以及pages文件夾以及layout.jade佈局文件,將原先views中的四個文件移動至pages文件中,在includes文件中新建head.jade文件與header.jade文件jquery
doctype
html
head
meta(chaset="utf-8")
title #{title}
include ./includes/head //- 將公用樣式抽象成一個區塊
body
include ./includes/header //-網站標題或者logo
block content //-每一個頁面中的內容
複製代碼
在編寫head.jade以及header.jade文件前,咱們首先安裝bower,而後經過bower安裝bootstrap
npm install bower -g
bower install bootstrap@3.3.7
//若是不加@3.3.7
會安裝最新的,致使頁面會出現一些顯示問題。git
link(href="/bootstrap/dist/css/bootstrap.min.css", rel="stylesheet")
script(src="/jquery/dist/jquery.min.js")
script(src="/bootstrap/dist/js/bootstrap.min.js")
複製代碼
.container
.row
.page-header
h1 #{title}
h3 六個周
複製代碼
extends ../layout
複製代碼
安裝成功後的項目結構是這樣的:web
此時,咱們再次終端輸入命令
node app
查看是否能夠正確訪問 ######注意app.js中訪問文件的路徑修改ajax
若是依然訪問成功,咱們繼續下一步操做。 咱們開始進行index.jade
(首頁)的文件編碼:。mongodb
extends ../layout
block content
.container
.row
each item in movies
.col-md-2
.thumbnai
a(href="/movie/#{item._id}")
img(src="#{item/poster}",alt="#{item.title}")
.caption
h3 #{title}
p: a.btn.btn-primary(href="/movie/#{item._id}",role="button")
觀看預告片
複製代碼
detail.jade
(詳情頁)文件:數據庫
extends ../layout
block content
.container
.row
.col-md-7
img(src="#{movie.poster}",alt="#{movie.title}",height="720")
.col-md-5
dl.horizontal
dt 電影名字
dd= movie.title
dt 導演
dd= movie.doctor
dt 國家
dd= movie.country
dt 語言
dd = movie.language
dt 上映年份
dd= movie.year
dt 簡介
dd = movie.summary
複製代碼
admin.jade
(後臺錄入頁)文件:express
extends ../layout
block content
.container
.row
form.form-horizontal(method="post",action="/admin/movie/new")
.form-group
label.col-sm-2.control-label(for="inputTitle") 電影名字
.col-sm-10
input#inputTitle.form-control(type="text",name="movie[title]",value="#{movie.title}")
.form-group
label.col-sm-2.control-label(for="inputDoctor") 電影導演
.col-sm-10
input#inputTitle.form-control(type="text",name="movie[doctor]",value="#{movie.doctor}")
.form-group
label.col-sm-2.control-label(for="inputCountry") 國家
.col-sm-10
input#inputTitle.form-control(type="text",name="movie[country]",value="#{movie.country}")
.form-group
label.col-sm-2.control-label(for="inputLanguage") 語種
.col-sm-10
input#inputTitle.form-control(type="text",name="movie[language]",value="#{movie.language}")
.form-group
label.col-sm-2.control-label(for="inputPoster") 海報地址
.col-sm-10
input#inputTitle.form-control(type="text",name="movie[poster]",value="#{movie.poster}")
.form-group
label.col-sm-2.control-label(for="inputFlash") 片源地址
.col-sm-10
input#inputTitle.form-control(type="text",name="movie[flash]",value="#{movie.flash}")
.form-group
label.col-sm-2.control-label(for="inputSummary") 電影簡介
.col-sm-10
textarea#inputSummary.form-control(type="text", name="movie[summary]", value="#{movie.summary}")
.form-group
.col-sm-offset-2.col-sm-10
button.btn.btn-default(type="submit") 錄入
複製代碼
list.jade
(列表頁)文件:
extends ../layout
block content
.container
.row
table.table.table-hover.table-bordered
thead
tr
th 電影名字
th 導演
th 國家
th 上映年份
//-th 錄入時間
th 查看
th 更新
th 刪除
tbody
each item in movies
tr(class="item-id-#{item._id}")
td #{item.title}
td #{item.doctor}
td #{item.country}
td #{item.year}
//-td #{moment(item.meta.createAt).format('MM/DD/YYYY')}
td :a(target="_blank",href="../movie/#{item._id}") 查看
td :a(target="_blank",href="../admin/update/#{item._id}") 修改
td
button.btn.btn-danger.del(type="button",data_id="#{item._id}") 刪除
複製代碼
僞造的靜態數據:app.js
var express = require('express')//加載express這個模塊
var app = express()
var path =require('path')
var port = process.env.PORT || 3000//設置端口:process是全局變量
app.set('views','./views/pages') //設置視圖的根目錄
app.set('view engine','jade')//設置默認的模板引擎
var bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(express.static(path.join(__dirname,'bower_components')))
app.listen(port)//監聽端口
console.log('六個周 started on port ' + port)//打印一條日誌,控制檯查看服務是否能成功啓動
//添加路由
//index page
app.get('/index',function(req,res){//瀏覽器中訪問頁面是以get方法提交提交的,參數一位匹配 規則,參數二爲回調方法
res.render('index',{
title:'六個周 首頁',
movies:[{
title:'Node.js指南',
_id:1,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg'
},{
title:'Node.js指南',
_id:2,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg'
},{
title:'Node.js指南',
_id:3,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg'
},{
title:'Node.js指南',
_id:4,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg'
},{
title:'Node.js指南',
_id:5,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg'
},{
title:'Node.js指南',
_id:6,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg'
},{
title:'Node.js指南',
_id:7,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg'
},{
title:'Node.js指南',
_id:8,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg'
},{
title:'Node.js指南',
_id:9,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg'
},{
title:'Node.js指南',
_id:10,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg'
},]
})
})
//detail page
app.get('/movie/:id',function(req,res){
res.render('detail',{
title:'detail 詳情頁',
movie:{
doctor:'六個周',
counter:'China',
title:'人生緣編程',
year:2019,
poster:'http://img4.imgtn.bdimg.com/it/u=1178625225,3686148785&fm=26&gp=0.jpg',
language:'漢語',
flash:'https://www.六個周.com/video/1226',
summary:'1.,生命過短暫,不要去作一些根本沒有人想要的東西。——Ash Maurya。2,若是你交給某人一個程序,你將折磨他一成天;若是你教某人如何編寫程序,你將折磨他一生。——David Leinweber。3,軟件設計有兩種方式:一種方式是,使軟件過於簡單,明顯沒有缺陷;另外一種方式是,使軟件過於複雜,沒有明顯的缺陷。——C.A.R. Hoare。4,軟件開發每每是這樣:最開始的 90% 代碼佔用了開始的 90% 的開發時間;剩下 10% 代碼一樣須要 90% 的開發時間。——Tom Cargill'
}
})
})
//admin page
app.get('/admin/movie',function(req,res){
res.render('admin',{
title:'六個周 後臺錄入頁',
movie:{
title:'',
doctor:'',
country:'',
year:'',
poster:'',
flash:'',
summary:'',
language:''
}
})
})
//list page
app.get('/admin/list',function(req,res){
res.render('list',{
title:'六個周 列表頁',
movies:[
{
title:'Node.js指南',
_id:1,
doctor:'六個周',
country:'China',
year:2019,
language:'漢語',
flash:'https://www.jianshu.com/u/5842abb77bd1',
summary:'1.,生命過短暫,不要去作一些根本沒有人想要的東西。——Ash Maurya。2,若是你交給某人一個程序,你將折磨他一成天;若是你教某人如何編寫程序,你將折磨他一生。——David Leinweber。3,軟件設計有兩種方式:一種方式是,使軟件過於簡單,明顯沒有缺陷;另外一種方式是,使軟件過於複雜,沒有明顯的缺陷。——C.A.R. Hoare。4,軟件開發每每是這樣:最開始的 90% 代碼佔用了開始的 90% 的開發時間;剩下 10% 代碼一樣須要 90% 的開發時間。——Tom Cargill'
}
]
})
複製代碼
})
而後,容易出錯的地方是bootstrap版本的安裝致使的頁面樣式以及jade的代碼縮進,通過一番調整後,啓動'node app
,效果圖以下:
#####而後,至此先將代碼提交至git於碼雲。 碼雲地址:gitee.com/ShaoBingYou…
在項目根目錄下新建文件夾schemas(模式聲明)、models(模型)、controllers。 分別在schemas中和models中添加movie.js文件,代碼以下:
schemas-movie.js
var mongoose =require('mongoose')
var MovieSchema =new mongoose.Schema({
doctor:String,
title:String,
language:String,
country:String,
summary:String,
flash:String,
poster:String,
year:Number,
meta:{
createaAt:{
type:Date,
default:Date.now()
},
updataAt:{
type:Date,
default:Date.now()
}
}
})
MovieSchema.pre('save',function(next){
if(this.isNew){
this.meta.createaAt = this.meta.updataAt =Date.now()
}else{
this.meta.updataAt =Date.now()
}
next()
})
MovieSchema.statics = {
fetch:function(cb){
return this
.find({})
.sort('meta.updateAt')
.exec(cb)
},
fingdById:function(id,cb){
return this
.findOne({_id:id})
.exec(cb)
}
}
module.exports =MovieSchema
複製代碼
models-movie.js
var mongoose =require('mongoose')
var MovieSchema = require('../schemas/movie')
var Movie = mongoose.model('Movie',MovieSchema)
module.exports = Movie
複製代碼
模式和模型代碼編寫結束,進入下一章節。
進入app.js文件,添加代碼 須要在終端中安裝underscore模塊:npm install underscore
var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost/imooc')
var Movie =require('./models/movie')
var _ =require('underscore')
#將app.js中的全部靜態數據註釋掉
複製代碼
index路由與list路由中添加 Movie.fetch()方法 detail路由中添加 Movie.findById()方法 admin路由中在路由外添加一個方法:app.post()
// admin post movie
app.post('/admin/movie/new',function(req,res){
var id =req.body.movie._id
var movieObj =req.body.movie
var _movie
if(id!== 'undefined'){
Movie.findById(id,function(err,mmovie){
if(err){
console.log(err)
}
_movie =_.extend(movie,movieObj)
_movie.save(function(err,movie){
if(err){
console.log(err)
}
res.redirect('./movie/'+movie.id)
})
})
}else{
_movie = new Movie({
doctor:movieObj.doctor,
title:movieObj.title,
country:movieObj.country,
language:movieObj.language,
year:movieObj.year,
poster:movieObj.poster,
summary:movieObj.summary,
flash:movieObj.flash
})
_movie.save(function(err,movie){
if (err) {
console.log(err)
}
res.redirect('/movie/'+movie._id)
})
}
})
複製代碼
還差一個在列表頁點擊更新的時候從新回到後臺錄入頁,將表單中數據從新初始化到表單中,因而添加一個路由
//admin update
app.get('/admin/update/:id',function(req,res){
var id =req.params.id
if(id){
Movie.findById(id,function(err,movie){
res.render('admin',{
title:'六個周 後臺更新頁',
movie: movie
})
})
}
})
複製代碼
最後還須要在admin錄入頁(admin.jade)添加一個隱藏的表單域,存儲電影ID,用於更新
input(type="hidden",name="movie[_id]",value="#{movie._id}")
複製代碼
而後咱們開始進行測試:
- 打開終端輸入
mongod
node app
後臺電影錄入頁:http://localhost:3000/admin/movie
localhost:3000/index
localhost:3000/admin/list
刪除功能這裏咱們須要使用jQuery,經過異步請求進行刪除。 在此以前,咱們須要改變項目結構,將
bower_components
中內容放在新建的一個public文件中。--這裏咱們須要用的bower的一個特性(能夠指定將bower下載的東西放在哪一個目錄下)。
- 項目根目錄下新建public文件夾
- 項目根目錄下新建 .bowerrc文件,在本文件下寫入以下代碼: { "directory": "public/libs" }
- 刪除bower_components文件夾
- 終端中從新安裝bootstrap:
bower install bootstrap@3.3.7
- 同時修改head.jade的bootstrap引入路徑,添加/libs
- 最好修改app.js中的bower_components改成public。至此,能夠再次輸入各個路徑進行測試 。
測試成功沒有問題,咱們繼續添加刪除的功能,在public文件下新建文件js,js中新建admin.js,編寫代碼:
$(function(){
$(".del").click(function(e){
var target = $(e.target)
var id =target.data('id')
var tr =$('.item-id-'+id)
$.ajax({
type:"DELETE",
url:'/admin/list?id='+id
})
.done(function(results){
if(results.success ===1){
if(tr.length>0){
tr.remove()
}
}
})
})
})
複製代碼
在list.jade中添加代碼
script(src="/js/admin.js")
複製代碼
在app.js中添加刪除路由:
//list delete movie
app.delete('/admin/list',function(req,res){
var id= req.query.id
if(id){
Movie.remove({_id: id},function(err,movie){
if(err){
console.log(err)
}else{
res.send({success:1})
}
})
}
})
複製代碼
https://gitee.com/ShaoBingYouTiao/movies
總結:至此建站攻略一期完畢,本項目對於不少不熟悉jade的同窗來講,可能會對寫jade代碼處有所抵觸,可是若是你按着我上面的思路一點一點寫出來的話仍是頗有收穫的。本項目中的代碼給出極可能~極可能的存在一兩個單詞的拼寫錯誤致使你在運行項目的時候出現問題,這個時候你要細細查看緣由,我已經儘量的將正確代碼貼上,若有問題,歡迎留言,我會在看到時及時回覆。
關於本項目的升級、二期學習與文檔整理我會盡快更新,先將地址貼上: 二期學習視頻慕課網地址:www.imooc.com/learn/197 二期學習簡書文檔整理地址:www.jianshu.com/p/a91924275…