慕课网nodejs建站第一期

项目地址

github

引用的nodejs库

  • express
  • path
  • mongoose
  • underscore
  • bodyParser

目录结构

  • models:用来存放mongoose model目录
  • public:静态文件
    • js:静态js库
    • libs:公共静态资源库
  • schemas:mongoose schemas目录
  • views:视图模板目录
    • includes:视图模板公共目录
    • pages:视图模板页面目录
    • layout.jade 视图主模板

数据库构建

schemas

数据存储结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
doctor:String,
title:String,
language:String,
country:String,
summary:String,
flash:String,
poster:String,
year:Number,
meta:{
createAt:{
type:Date,
default:Date.now()
},
updateAt:{
type:Date,
default:Date.now()
}
}

数据存储方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//每次存储数据都会调用这个函数 类似于路由中间件
MovieSchema.pre("save",function(next){
if(this.isNew){
this.meta.createAt=this.meta.updateAt=Date.now()
}else{
this.meta.updateAt=Date.now()
}
next()
})
//经过模型编译后才会具有这些方法
MovieSchema.statics={
fetch:function(cb){
return this.find({}).sort("meta.updateAt").exec(cb)
},
findById:function(id,cb){
return this.findOne({_id:id}).sort("meta.updateAt").exec(cb)
}
}

models

存储在Movie集合中,存储结构为schema

1
var Movie=mongoose.model("Movie",MovieSchema)

路由构建

首页(index)路由

访问首页的时候获取movie集合中所有的数据并且传递数据渲染index视图模板

1
2
3
4
5
6
7
8
9
10
11
12
//index page
app.get("/", function (req, res) {
Movie.fetch(function (err, movies) {
if (err) {
console.log(err)
}
res.render("index", {
title: "imooc 首页",
movies: movies
})
})
});

详情页(detail)路由

当访问的方式为/movie/:id //id为数据库中唯一存在的_id值
获取movie集合中_id为:id的数据并且渲染detail视图

1
2
3
4
5
6
7
8
9
10
11
//detail page
app.get("/movie/:id", function (req, res) {
var id = req.params.id;
Movie.findById(id, function (err, movie) {
res.render("detail", {
title: "imooc " + movie.title,
movie: movie
})
})
});

录入页(admin/movie)路由

渲染admin视图传递空字符串过去.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//admin page
app.get("/admin/movie", function (req, res) {
res.render("admin", {
title: "imooc 后台录入页",
movie: {
title: "",
doctor: "",
country: "",
year: "",
poster: "",
flash: "",
summary: "",
language: ""
}
})
});

更新页(admin/update)路由

获取传递的id同时渲染admin视图 把movie中找到的数据传递过去

1
2
3
4
5
6
7
8
9
10
11
12
13
//admin update movie
app.get("/admin/update/:id",function(req,res){
var id=req.params.id
if(id){
Movie.findById(id,function(err,movie){
console.log(72,movie)
res.render("admin",{
title:"后台更新页",
movie:movie
})
})
}
})

数据更新(post,update)路由

当更新页/录入页 点击录入的时候传递表单内容至/admin/movie/new
判断传递过来的id是否存在,如果存在则认为不是新录入.更新数据后调用model.save方法保存到数据库
如果不存在则调用model.save方法直接保存到数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//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, movie) {
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/list)路由

传递所有的movie渲染list视图

1
2
3
4
5
6
7
8
9
10
11
12
//list page
app.get("/admin/list", function (req, res) {
Movie.fetch(function (err, movies) {
if (err) {
console.log(err)
}
res.render("list", {
title: "imooc 列表页",
movies:movies
})
})
});

列表页删除(delete,/admin/list)路由

当在列表页点击删除时发起一段ajax请求 如果成功后台返回success:1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.json({success:1})
}
})
}
})

结尾

因为是第一期所以没实现用户,权限管理登内容…有啥问题直接blog留言即可