Node + MongoDB 建站 1期

项目初始化

建立Imooc文件夹,在文件夹根目录下安装模块

npm install express  jade  mongoose  bootstrap@3
npm install bower -g

项目结构目录如下

- Imooc/
    -node_modules/
    -bower_components/
    -views/
        -index.jade
        -detail.jade
        -admin.jade
        -list.jade
    -app.js

测试地址

localhost:3000/
localhost:3000/movie/1
localhost:3000/admin/movie
localhost:3000/admin/list

入口文件app.js

var express = require('express')
var app = express()

app.set('view engine','jade')
app.set('port',3000)

app.get('/',function(req,res){
    res.render('index',{title:'imooc'})
})

创建入口文件及视图

修改app.js文件,配置路由

var express = require('express')
var port = process.env.port || 3000 
var app = express()

app.set('views', './views')
app.set('view engine','jade')
app.listen(port)

console.log('Imooc started on port' + port)

//index page
app.get('/',function(req,res){
    res.render('index',{title:'imooc 首页'})
})

//detail page
app.get('/movie/:id',function(req,res){
    res.render('detail',{title:'imooc 详情页'})
})

//admin page
app.get('/admin/movie',function(req,res){
    res.render('admin',{title:'imooc 后台录入页'})
})

//list page
app.get('/admin/list',function(req,res){
    res.render('list',{title:'imooc 列表页'})
})

创建4个jade视图,代码如下

doctype
html
    head
        meta(chareset="utf-8")
        title #{title}
    body
        h1 #{title}

在cmd命令中以node app 启动项目,查看浏览器

页面开发

创建如下view结构



head文件中引入js css

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文件中为公用代码

.container
  .row
    .page-header
      h1= title
      small 重度科幻迷

layout文件如下

doctype
html
    head
        meta(chareset="utf-8")
        title #{title}
        include ./includes/head
    body
        include ./includes/header
        block content
        h1 #{title}

修改index,继承layout,根据movies创建thumbnail缩略图

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
                      h4 #{item.title}
                      p: a.btn.btn-primary(href="/movie/#{item._id}", role="button") 观看预告片

修改detail,左边flash插件,右边movie内容

extends ../layout

block content
  .container
    .row
      .col-md-7
        embed(src="#{movie.flash}", allowFullScreen="true", quality="high", width="720", height="600", align="middle", type="application/x-shockwave-flash")
      .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,加入form表单组件

extends ../layout

block content
 .container
   .row
     form.form-horizontal(method="post", action="/admin/movie")
       .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="uploadPoster") 海报上传
         .col-sm-10
           input#uploadPoster(type="file", name="uploadPoster")
       .form-group
         label.col-sm-2.control-label(for="inputFlash") 片源地址
         .col-sm-10
           input#inputFlash.form-control(type="text", name="movie[flash]", value=movie.flash)
       .form-group
         label.col-sm-2.control-label(for="inputYear") 上映年代
         .col-sm-10
           input#inputYear.form-control(type="text", name="movie[year]", value=movie.year)
       .form-group
         label.col-sm-2.control-label(for="inputSummary") 电影简介
         .col-sm-10
           textarea#inputSummary.form-control(type="text", name="movie[summary]")= movie.summary
       .form-group
         .col-sm-offset-2.col-sm-10
         button.btn.btn-default(type="submit") 录入

修改list 加入table组件

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.updateAt).format('MM/DD/YYYY')}
              td: a(target="_blank", href="/movie/#{item._id}") 查看
              td: a(target="_blank", href="/admin/movie/update/#{item._id}") 修改
              td
                button.btn.btn-danger.del(type="button", data-id="#{item._id}") 删除

修改app.js ,添加path模块来制定文件夹,在page中传入mock数据

var express = require('express')
var path = require('path')
var port = process.env.PORT || 3000
var app = express()
var bodyParser = require('body-parser')

app.set('views', './views/pages')
app.set('view engine', 'jade')
app.use(bodyParser.urlencoded({extended:true}))
app.use(express.static(path.join(__dirname, 'node_modules')))
app.listen(port)

console.log('imooc stated on port ' + port)

//index page
app.get('/', function(req, res) {
    res.render('index', {
        title: 'imooc 首页',
        movies: [{
            title: '机械战警',
            _id: 1,
            poster: 'http://r3.ykimg.com/05160000530EEB63675839160D0B79D5'
        },
        {
            title: '机械战警',
            _id: 2,
            poster: 'http://r3.ykimg.com/05160000530EEB63675839160D0B79D5'
        },
        {
            title: '机械战警',
            _id: 3,
            poster: 'http://r3.ykimg.com/05160000530EEB63675839160D0B79D5'
        },
        {
            title: '机械战警',
            _id: 4,
            poster: 'http://r3.ykimg.com/05160000530EEB63675839160D0B79D5'
        },
        {
            title: '机械战警',
            _id: 5,
            poster: 'http://r3.ykimg.com/05160000530EEB63675839160D0B79D5'
        },
        {
            title: '机械战警',
            _id: 6,
            poster: 'http://r3.ykimg.com/05160000530EEB63675839160D0B79D5'
        }]
    })
})

//detail page
app.get('/movie/:id', function(req, res) {
    res.render('detail', {
        title: 'imooc 详情页',
        movie: {
        doctor: '何塞·帕迪里亚',
        country: '美国',
        title: '机械战警',
        year: '2014',
        poster: 'http://r3.ykimg.com/05160000530EEB63675839160D0B79D5',
        language: '英语',
        flash: 'http://player.youku.com/player.php/sid/XNjA1Njc0NTUy/v.swf',
        summary: '《机械战警》是由何塞·帕迪里亚执导,乔尔·金纳曼、塞缪尔·杰克逊、加里·奥德曼等主演的一部科幻电影,改编自1987年保罗·范霍文执导的同名电影。影片于2014年2月12日在美国上映,2014年2月28日在中国大陆上映。影片的故事背景与原版基本相同,故事设定在2028年的底特律,男主角亚历克斯·墨菲是一名正直的警察,被坏人安装在车上的炸弹炸成重伤,为了救他,OmniCorp公司将他改造成了生化机器人“机器战警”,代表着美国司法的未来。'
        }
    })
})

//admin page
app.get('/admin/movie', function(req, res) {
    res.render('admin', {
        title: 'imooc 后台录入页',
        movie: {
            title: '',
            doctor: '',
            country: '',
            year: '',
            poster: '',
            flash: '',
            summary: '',
            language: ''
        }
    })
})

//list page
app.get('/admin/list', function(req, res) {
    res.render('list', {
        title: 'imooc 列表页',
        movies: [{
            title: '机械战警',
            _id: 1,
            doctor: '何塞·帕迪里亚',
            country: '美国',
            year: 2014,
            language: '英语',
            flash: 'http://player.youku.com/player.php/sid/XNjA1Njc0NTUy/v.swf',
            summary: '《机械战警》是由何塞·帕迪里亚执导,乔尔·金纳曼、塞缪尔·杰克逊、加里·奥德曼等主演的一部科幻电影,改编自1987年保罗·范霍文执导的同名电影。影片于2014年2月12日在美国上映,2014年2月28日在中国大陆上映。影片的故事背景与原版基本相同,故事设定在2028年的底特律,男主角亚历克斯·墨菲是一名正直的警察,被坏人安装在车上的炸弹炸成重伤,为了救他,OmniCorp公司将他改造成了生化机器人“机器战警”,代表着美国司法的未来。'
        }]
    })
})

启动应用查看浏览器


项目数据库实现

Mongo DB 通过 Schema Model Document来进行数据库的定义操作



建立模式 schemas/movie.js,定义MovieSchema结构,添加pre方法及静态方法,最后将其导出

var mongoose = require('mongoose')
var Schema = mongoose.Schema

var MovieSchema = new Schema({
  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()
    }
  }
})

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)
    }
  }
  
module.exports = MovieSchema

建立模型 models/movie.js,通过MovieSchema对模式进行编译建立模型,最后将其导出

var mongoose = require('mongoose')
var MovieSchema = require('../schemas/movie')
var Movie = mongoose.model('Movie', MovieSchema)

module.exports = Movie

修改app.js如下,安装npm install underscore moment,本地MongoDB创建DB imooc。
index page中,Movie模型调用fetch方法得到movies数据集
detail page中,Movie模型调用findById方法,通过req中参数取得id
admin page中,提交表单调用post方法,id为空创建新对象,id不为空扩展对象
list page中,与index类似读取movies数据集
添加update路由

var express = require('express')
var path = require('path')
var mongoose = require('mongoose')
var _ = require('underscore')
var Movie = require('./models/movie')
var port = process.env.PORT || 3000
var app = express()
var bodyParser = require('body-parser')

mongoose.connect('mongodb://localhost/imooc')

app.set('views', './views/pages')
app.set('view engine', 'jade')
app.use(bodyParser.urlencoded({extended:true}))
app.use(express.static(path.join(__dirname, 'node_modules')))
app.locals.moment = require('moment')
app.listen(port)

console.log('imooc stated on port ' + port)

//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 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: movie
        })
    })

})

//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 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: 'Imooc 后台更新页',
                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

    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({
            dector: movieObj.dector,
            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: 'imooc 列表页',
            movies: movies
        })
    })
})

在admin.jade添加隐藏的input,记录id

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

删除功能及配置文件

创建public目录,创建文件public/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文件末尾引入admin.js

script(src="/js/admin.js")

创建.bowerrc文件,制定bower安装目录

{
    "directory": "public/libs"
}

用bower安装bootstrap bower install bootstrap@3
修改app.js中path路径 app.use(express.static(path.join(__dirname, 'public')))
修改head.jade

link(href="/libs/bootstrap/dist/css/bootstrap.min.css", rel="stylesheet")
script(src="/libs/jquery/dist/jquery.min.js")
script(src="/libs/bootstrap/dist/js/bootstrap.min.js")

在app.js添加delete路由

//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.json({success: 1})
            }
        })
    }
})

前端配置文件生成 bower init
后端配置文件生成 npm init

上传项目到GIT

在码云上创建项目



复制SSH地址



项目目录下创建.gitignore文件,忽略下列文件夹
/node_modules/
/public/libs

在项目根目录下启用Git Bash,git init初始化
git remote add origin (ssh copy)将本地目录与github关联
git pull origin master拉取master分支
git status查看状态
git add .把文件追踪上
git commit -am 'test' / git ca 'test'提交并加上test注释
git push --set-upstream origin master推送到远程master分支
git checkout -b v1.0.0创建v1.0.0分支并checkout
git branch查看分支



查看github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容