最近做了一个小例子,想通过这个例子梳理以下思路,了解这三者之间是如何进行前后端交互,现将该项目的过程及思路记录如下。
一.项目展示
1.主界面
2.录入界面
3.后台管理界面
二.工程创建
1.创建目录结构如下:
其中,pages文件夹内放置页面文件,models/schemas/views与mongodb数据库有关,bower_components内放置bower下载的css/js库。layout.jade是界面模板,app.js是程序入口。
2.界面搭建
2.1 准备工作
head.jade
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")
header.jade
.container
.row
.page-header
h1=title
small 重度科幻迷
layout.jade
doctype
html
head
meta(charset="utf-8")
title #{title}
include ./includes/head
body
include ./includes/header
block content
2.2 界面代码
index.jade
extends ../layout
block content
.container
.row
each item in movies
.col-md-2
.thumbnail
a(href="/movie/#{item._id}")
img(src="#{item.poster}",alt="#{item.title}")
.caption
h3 #{item.title}
p: a.btn.btn-primary(href="/movie/#{item._id}",role="button")
观看预告片
admin.jade
extends ../layout
block content
.container
.row
form.form-horizontal(method="post",action="/admin/movie/new")
input(type="hidden",name="movie[_id]",value="#{movie._id}")
.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#inputDoctor.form-control(type="text",name="movie[doctor]",value="#{movie.doctor}")
.form-group
label.col-sm-2.control-label(for="inputCountry")国家
.col-sm-10
input#inputCountry.form-control(type="text",name="movie[country]",value="#{movie.country}")
.form-group
label.col-sm-2.control-label(for="inputLanguage")语种
.col-sm-10
input#inputLanguage.form-control(type="text",name="movie[language]",value="#{movie.language}")
.form-group
label.col-sm-2.control-label(for="inputPoster")海报地址
.col-sm-10
input#inputPoster.form-control(type="text",name="movie[poster]",value="#{movie.poster}")
.form-group
label.col-sm-2.control-label(for="inputDoctor")片源地址
.col-sm-10
input#inputFlash.form-control(type="text",name="movie[flash]",value="#{movie.flash}")
.form-group
label.col-sm-2.control-label(for="inputDoctor")上映年代
.col-sm-10
input#inputYear.form-control(type="text",name="movie[year]",value="#{movie.year}")
.form-group
label.col-sm-2.control-label(for="inputDoctor")电影简介
.col-sm-10
input#inputSummary.form-control(type="text",name="movie[summary]",value="#{movie.summary}")
.form-group
label.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 删除
tbody
each item in movies
tr(class="item-id-#{item._id}")
td #{item.title}
td #{item.doctor}
td #{item.country}
td #{item.year}
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}")删除
detail.jade
extends ../layout
block content
.container
.row
.col-md-7
embed(src="#{movies.flash}",allowFullScreen="true",quality="high",width="720",height="600",align="middle",type="application/x-shockwave-flash")
.col-md-5
dl.dl-horizontal
dt 电影名字
dd=movies.title
dt 导演
dd=movies.doctor
dt 国家
dd=movies.country
dt 语言
dd=movies.language
dt 上映年份
dd=movies.year
dt 简介
dd=movies.summary
3.app.js路由构建与数据准备
var express = require('express'); // 加载express模块
var mongoose = require('mongoose'); // 加载mongoose模块
var app = express(); // 启动Web服务器
var port = process.env.PORT || 3000; // 设置端口号
app.listen(port);
console.log('i_movie start on port' + port);
var path = require('path');
// 请求样式或脚本,去bower_components下去查找
mongoose.connect('mongodb://localhost:27017/imovie');
console.log('MongoDB connection success!');
app.locals.moment = require('moment'); // 载入moment模块,格式化日期
var serveStatic = require('serve-static'); // 静态文件处理
app.use(serveStatic('bower_components'));
var bodyParser = require('body-parser');
// 因为后台录入页有提交表单的步骤,故加载此模块方法(bodyParser模块来做文件解析),将表单里的数据进行格式化
app.use(bodyParser.urlencoded({extended: true}));
var _underscore = require('underscore'); // _.extend用新对象里的字段替换老的字段
app.set('views', './views/pages'); // 设置视图默认的文件路径
app.set('view engine', 'jade'); // 设置视图引擎:jade
var movie = require('./models/movie.js'); // 载入mongoose编译后的模型movie
// 编写主要页面路由
// index page 首页
app.get('/', function (req, res) {
//后期与数据库对接
});
// detail page 详情页
app.get('/movie/:id', function (req, res) {
var id = req.params.id;
//后期与数据库对接
});
// admin page 后台录入页
app.get('/admin/movie', function (req, res) {
res.render('admin', {
title: 'i_movie 后台录入页',
movie: {
title: '',
doctor: '',
country: '',
year: '',
poster: '',
flash: '',
summary: '',
language: ''
}
});
});
// admin update movie 后台更新页
app.get('/admin/update/:id', function (req, res) {
var id = req.params.id;
if (id) {
//后期与数据库对接
}
});
// admin post movie 后台录入提交
app.post('/admin/movie/new', function (req, res) {
var id = req.body.movie._id;
var movieObj = req.body.movie;
var _movie = null;
//后期与数据库对接
});
// list page 列表页
app.get('/admin/list', function (req, res) {
movie.fetch(function (err, movies) {
//后期与数据库对接
});
});
// list delete movie data 列表页删除电影
app.delete('/admin/list', function (req, res) {
var id = req.query.id;
//后期与数据库对接
});
4.mongodb数据库相关
schemas/movie.js
var mongoose = require('mongoose');
var movieSchema = new mongoose.Schema({
title: String,
doctor: String,
language: String,
country: String,
summary: String,
flash: String,
poster: String,
year: Number,
// meta 更新或录入数据的时间记录
meta: {
createAt: {
type: Date,
default: Date.now()
},
updateAt: {
type: Date,
default: Date.now()
},
}
});
// movieSchema.pre 表示每次存储数据之前都先调用这个方法
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})
.exec(cb)
}
}
// 导出movieSchema模式
module.exports = movieSchema;
models/movie.js
var mongoose = require('mongoose');
var movieSchema = require('../schemas/movie.js');
// 编译生成movie模型
var movie = mongoose.model('movie', movieSchema);
module.exports = movie;
5.与mongodb进行对接代码
修改app.js为
/ 编写主要页面路由
// index page 首页
app.get('/', function (req, res) {
movie.fetch(function (err, movies) {
if (err) {
console.log(err);
}
res.render('index', { // 渲染index 首页
title: 'i_movie 首页',
movies: movies
});
});
});
// detail page 详情页
app.get('/movie/:id', function (req, res) {
var id = req.params.id;//获取到请求里的id
movie.findById(id, function (err, movie) {
res.render('detail', {
title: 'i_movie' + movie.title,
movie: movie
});
});
});
// admin page 后台录入页
app.get('/admin/movie', function (req, res) {
res.render('admin', {
title: 'i_movie 后台录入页',
movie: {
title: '',
doctor: '',
country: '',
year: '',
poster: '',
flash: '',
summary: '',
language: ''
}
});
});
// admin update movie 后台更新页
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: 'imovie 后台更新页',
movie: movie
});
});
}
});
// admin post movie 后台录入提交
app.post('/admin/movie/new', function (req, res) {
var id = req.body.movie._id;
var movieObj = req.body.movie;
var _movie = null;
if (id !== 'undefined') { // 已经存在的电影数据
movie.findById(id, function (err, movie) {
if (err) {
console.log(err);
}
_movie = _underscore.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);
});
}
});
// list page 列表页
app.get('/admin/list', function (req, res) {
movie.fetch(function (err, movies) {
if (err) {
console.log(err);
}
res.render('list', {
title: 'i_movie 列表页',
movies: movies
});
});
});
// list delete movie data 列表页删除电影
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});
}
});
}
});
以上是整个代码的流程,下一阶段需要对express.js以及mongodb.js做一个深入的了解,欢迎交流。