您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)如何使用NodeJS+MongoDB+AngularJS+Bootstrap開發(fā)書店項(xiàng)目的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
示例名稱:天狗書店
功能:完成前后端分離的圖書管理功能,總結(jié)前端學(xué)習(xí)過的內(nèi)容。
技術(shù):NodeJS、Express、Monk、MongoDB、AngularJS、BootStrap、跨域
效果:
一、Bootstrap
Bootstrap是一個(gè)UI框架,它支持響應(yīng)式布局,在PC端與移動端都表現(xiàn)不錯(cuò)。
Bootstrap是Twitter推出的一款簡潔、直觀、強(qiáng)悍的前端開發(fā)框架。
Bootstrap中包含了豐富的Web組件,根據(jù)這些組件,可以快速的搭建一個(gè)漂亮、功能完備的網(wǎng)站。
在線可視布局:http://www.ibootstrap.cn/
演示: http://expo.bootcss.com/
中文網(wǎng):http://www.bootcss.com/
官網(wǎng):http://getbootstrap.com/
安裝:npm install bootstrap@3
1.1、添加引用
也可使用包管理器也可以去官網(wǎng)下載后添加引用。
1.2、在頁面中使用BootStrap
添加CSS引用:
<link rel="stylesheet" type="text/css" href="js/bootstrap/dist/css/bootstrap.min.css" />
添加JavaScript引用:
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script src="js/bootstrap/dist/js/bootstrap.min.js" type="text/javascript" charset="utf-8"></script>
在頁面中引用BootStrap定義好的樣式
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>bootstrap</title> <link rel="stylesheet" type="text/css" href="js/bootstrap/dist/css/bootstrap.min.css" /> </head> <body> <div class="container-fluid"> <div class="row"> <div class="jumbotron"> <h2>Hello, world!</h2> <p>This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information</p> <p> <a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a> </p> </div> </div> <div class="row"> <div class="col-md-6"> <button type="button" class="btn btn-default">默認(rèn)</button> <button type="button" class="btn btn-primary">主要</button> <button type="button" class="btn btn-success">成功</button> <button type="button" class="btn btn-info">信息</button> <button type="button" class="btn btn-warning">警告</button> <button type="button" class="btn btn-danger">錯(cuò)誤</button> <button type="button" class="btn btn-link">鏈接</button> </div> <div class="col-md-6"> <button type="button" class="btn btn-default btn-lg">默認(rèn)</button> <button type="button" class="btn btn-default">默認(rèn)</button> <button type="button" class="btn btn-default btn-sm">默認(rèn)</button> <button type="button" class="btn btn-default btn-xs">默認(rèn)</button> </div> </div> </div> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script src="js/bootstrap/dist/js/bootstrap.min.js" type="text/javascript" charset="utf-8"></script> </body> </html>
運(yùn)行結(jié)果:
1.3、可視化布局
如果想快速高效的布局可以使用一些在線輔助工具,如:
http://www.ibootstrap.cn/
點(diǎn)擊下載可以獲得生成的HTML腳本。
二、使用MongoDB創(chuàng)建數(shù)據(jù)庫
2.1、啟動MongoDB數(shù)據(jù)庫
數(shù)據(jù)庫的具體安裝、配置在前面的章節(jié)中已經(jīng)講解過,可以參考。
如果服務(wù)與配置都沒有完成的話可以啟動:C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe
2.2、啟動數(shù)據(jù)庫GUI管理工具
2.3、創(chuàng)建數(shù)據(jù)庫與集合
在localhost上右鍵“create database”創(chuàng)建名稱為BookStore的數(shù)據(jù)庫。
創(chuàng)建一個(gè)用于存放圖書的集合名稱為books。
在集合中添加5本圖書。
db.getCollection('books').insert({id:201701,title:"使用AlarJS開發(fā)下一代應(yīng)用程序",picture:"b1.jpg",price:55.0,author:"brad green"});
三、創(chuàng)建一個(gè)Express項(xiàng)目
這里使用Eclipse(HBuilder)為開發(fā)工具,添加Nodeclipse插件,新增一個(gè)Express項(xiàng)目:
3.1、創(chuàng)建app.js
/** * Module dependencies. */ var express = require('express') , routes = require('./routes') , books = require('./routes/books') , http = require('http') , path = require('path'); var app = express(); // all environments app.set('port', process.env.PORT || 3000); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); app.use(express.favicon()); app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(path.join(__dirname, 'public'))); // development only if ('development' == app.get('env')) { app.use(express.errorHandler()); } app.get('/', books.list); app.get('/books', books.list); http.createServer(app).listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port')); });
四、Monk訪問MongoDB數(shù)據(jù)庫
monk是NodeJS平臺下訪問MongoDB數(shù)據(jù)庫的一個(gè)模塊。monk訪問MongoDB更加方便比NodeJS直接訪問。
git倉庫地址:https://github.com/Automattic/monk
文檔:https://automattic.github.io/monk/
安裝:npm install --save monk
4.1、創(chuàng)建連接
const monk = require('monk') // Connection URL const url = 'localhost:27017/myproject'; const db = monk(url); db.then(() => { console.log('Connected correctly to server') })
4.2、插入數(shù)據(jù)
const url = 'localhost:27017/myproject'; // Connection URL const db = require('monk')(url); const collection = db.get('document') collection.insert([{a: 1}, {a: 2}, {a: 3}]) .then((docs) => { // docs contains the documents inserted with added **_id** fields // Inserted 3 documents into the document collection }).catch((err) => { // An error happened while inserting }).then(() => db.close()) users.insert({ woot: 'foo' }) users.insert([{ woot: 'bar' }, { woot: 'baz' }])
4.3、更新數(shù)據(jù)
const url = 'localhost:27017/myproject'; // Connection URL const db = require('monk')(url); const collection = db.get('document') collection.insert([{a: 1}, {a: 2}, {a: 3}]) .then((docs) => { // Inserted 3 documents into the document collection }) .then(() => { return collection.update({ a: 2 }, { $set: { b: 1 } }) }) .then((result) => { // Updated the document with the field a equal to 2 }) .then(() => db.close()) users.update({name: 'foo'}, {name: 'bar'})
4.4、刪除數(shù)據(jù)
const url = 'localhost:27017/myproject'; // Connection URL const db = require('monk')(url); const collection = db.get('document') collection.insert([{a: 1}, {a: 2}, {a: 3}]) .then((docs) => { // Inserted 3 documents into the document collection }) .then(() => collection.update({ a: 2 }, { $set: { b: 1 } })) .then((result) => { // Updated the document with the field a equal to 2 }) .then(() => { return collection.remove({ a: 3}) }).then((result) => { // Deleted the document with the field a equal to 3 }) .then(() => db.close()) users.remove({ woot: 'foo' })
4.5、查找數(shù)據(jù)
const url = 'localhost:27017/myproject'; // Connection URL const db = require('monk')(url); const collection = db.get('document') collection.insert([{a: 1}, {a: 2}, {a: 3}]) .then((docs) => { // Inserted 3 documents into the document collection }) .then(() => collection.update({ a: 2 }, { $set: { b: 1 } })) .then((result) => { // Updated the document with the field a equal to 2 }) .then(() => collection.remove({ a: 3})) .then((result) => { // Deleted the document with the field a equal to 3 }) .then(() => { return collection.find() }) .then((docs) => { // docs === [{ a: 1 }, { a: 2, b: 1 }] }) .then(() => db.close())
users.find({}).then((docs) => {}) users.find({}, 'name').then((docs) => { // only the name field will be selected }) users.find({}, { fields: { name: 1 } }) // equivalent users.find({}, '-name').then((docs) => { // all the fields except the name field will be selected }) users.find({}, { fields: { name: 0 } }) // equivalent users.find({}, { rawCursor: true }).then((cursor) => { // raw mongo cursor }) users.find({}).each((user, {close, pause, resume}) => { // the users are streaming here // call `close()` to stop the stream }).then(() => { // stream is over }) //創(chuàng)建的數(shù)據(jù)庫 var monk = require('monk') var db = monk('localhost:27017/bookstore') //讀取數(shù)據(jù): var monk = require('monk') var db = monk('localhost:27017/monk-demo') var books = db.get('books') books.find({}, function(err, docs) { console.log(docs) }) //插入數(shù)據(jù): books.insert({"name":"orange book","description":"just so so"}) //查找數(shù)據(jù): books.find({"name":"apple book"}, function(err, docs) { console.log(docs) }) 復(fù)制代碼 五、創(chuàng)建Rest后臺服務(wù) 在routes目錄下增加的books.js文件內(nèi)容如下: 復(fù)制代碼 /* * 使用monk訪問mongodb * 以rest的方式向前臺提供服務(wù) */ //依賴monk模塊 var monk = require('monk'); //連接并打開數(shù)據(jù)庫 var db = monk('localhost:27017/BookStore'); //從數(shù)據(jù)庫中獲得books集合,類似表,并非所有數(shù)據(jù), key var books = db.get('books'); //列出所有的圖書json exports.list = function(req, res) { //無條件查找所有的圖書,then是當(dāng)查找完成時(shí)回調(diào)的異步方法 books.find({}).then((docs) => { //返回json給客戶端 res.json(docs); }).then(() => db.close()); //關(guān)閉數(shù)據(jù)庫 }; //獲得最大id exports.getMax=function(req,res){ //找一個(gè),根據(jù)id降序排序, books.findOne({}, {sort: {id: -1}}).then((bookObj)=>{ res.json(bookObj); }).then(() => db.close());; } //添加圖書 exports.add = function(req, res) { //先找到最大的圖書編號 books.findOne({}, {sort: {id: -1}}).then((obj)=>{ //從客戶端發(fā)送到服務(wù)器的圖書對象 var book=req.body; //設(shè)置圖書編號為最大的圖書編號+1 book.id=(parseInt(obj.id)+1)+""; //執(zhí)行添加 books.insert(book).then((docs) => { //返回添加成功的對象 res.json(docs); }).then(() => db.close()); }); }; //刪除圖書 exports.del = function(req, res) { //從路徑中取參數(shù)id,/:id var id=req.params.id; //移除編號為id的圖書 books.remove({"id":id}).then((obj)=>{ //返回移除結(jié)果 res.json(obj); }).then(() => db.close()); }; //更新 exports.update = function(req, res) { //獲得提交給服務(wù)器的json對象 var book=req.body; //執(zhí)行更新,第1個(gè)參數(shù)是要更新的圖書查找條件,第2個(gè)參數(shù)是要更新的對象 books.update({"id":book.id}, book).then((obj)=>{ //返回更新完成后的對象 res.json(obj); }).then(() => db.close()); };
為了完成跨域請求,修改http頭部信息及路徑映射,app.js文件如下:
var express = require('express'), routes = require('./routes'), books = require('./routes/books'), http = require('http'), path = require('path'); var app = express(); // all environments app.set('port', process.env.PORT || 3000); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); app.use(express.favicon()); app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(path.join(__dirname, 'public'))); app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "content-type"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); res.header("X-Powered-By", ' 3.2.1') res.header("Content-Type", "application/json;charset=utf-8"); if(req.method == "OPTIONS") { res.send("200"); } else { next(); } }); // development only if('development' == app.get('env')) { app.use(express.errorHandler()); } app.get('/', books.list); //獲得所有的圖書列表 app.get('/books', books.list); //最大的編號 app.get('/books/maxid', books.getMax); //添加 app.post('/books/book', books.add); //刪除 app.delete('/books/id/:id', books.del); //更新 app.put('/books/book', books.update); http.createServer(app).listen(app.get('port'), function() { console.log('Express server listening on port ' + app.get('port')); });
查詢所有:
其它服務(wù)的測試可以使用Fiddler完成。
六、使用AngularJS調(diào)用后臺服務(wù)
這里的UI使用BootStrap完成,前端使用AngularJS調(diào)用NodeJS發(fā)布的服務(wù),將數(shù)據(jù)存放在MongoDB中。
index.js頁面如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>天狗書店</title> <link rel="shortcut icon" href="favicon.ico" /> <link rel="bookmark" href="favicon.ico" /> <link rel="stylesheet" type="text/css" href="js/bootstrap/dist/css/bootstrap.min.css" /> <style type="text/css"> .cover { height: 40px; width: auto; } .addBook { padding-top: 10px; } .w100 { width: 50px } .w200 { width: 200px; } .w300 { width: 300px } </style> </head> <body ng-app="bookApp"> <div class="container" ng-controller="BookController"> <div class="row clearfix"> <div class="col-md-12 column"> <nav class="navbar navbar-default" role="navigation"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button> <a class="navbar-brand" href="#">天狗書店</a> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"> <a href="#">前端</a> </li> <li> <a href="#">Java</a> </li> <li> <a href="#">.Net</a> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">更多類型<strong class="caret"></strong></a> <ul class="dropdown-menu"> <li> <a href="#">Action</a> </li> <li> <a href="#">Another action</a> </li> <li> <a href="#">Something else here</a> </li> <li class="divider"> </li> <li> <a href="#">Separated link</a> </li> <li class="divider"> </li> <li> <a href="#">One more separated link</a> </li> </ul> </li> </ul> <form class="navbar-form navbar-left" role="search"> <div class="form-group"> <input type="text" class="form-control" /> </div> <button type="submit" class="btn btn-default">搜索</button> </form> </div> </nav> <div class="row clearfix"> <div class="col-md-12 column"> <div class="carousel slide" id="carousel-519027"> <ol class="carousel-indicators"> <li class="active" data-slide-to="0" data-target="#carousel-519027"> </li> <li data-slide-to="1" data-target="#carousel-519027"> </li> <li data-slide-to="2" data-target="#carousel-519027"> </li> </ol> <div class="carousel-inner"> <div class="item active"> <img src="img/adv3.jpg" /> <div class="carousel-caption"> </div> </div> <div class="item"> <img src="img/adv2.jpg" /> <div class="carousel-caption"> </div> </div> <div class="item"> <img src="img/adv1.jpg" /> <div class="carousel-caption"> <h5> Third Thumbnail label </h5> <p> Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit. </p> </div> </div> </div> <a class="left carousel-control" href="#carousel-519027" data-slide="prev"><span class="glyphicon glyphicon-chevron-left"></span></a> <a class="right carousel-control" href="#carousel-519027" data-slide="next"><span class="glyphicon glyphicon-chevron-right"></span></a> </div> </div> </div> </div> </div> <div class="row clearfix"> <div class="col-md-12 column"> <div class="addBook"> <a id="modal-234446" href="#modal-container-234446" role="button" class="btn btn-sm btn-primary" data-toggle="modal"><span class="glyphicon glyphicon-plus"></span> 新書上架</a> <div class="modal fade" id="modal-container-234446" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h5 class="modal-title" id="myModalLabel"> 添加/編輯圖書 </h5> </div> <div class="modal-body"> <form class="form-horizontal" role="form"> <div class="form-group"> <label for="id" class="col-sm-2 control-label">編號</label> <div class="col-sm-10"> <input type="text" class="form-control w100" id="id" ng-model="book.id" ng-readonly="true" /> </div> </div> <div class="form-group"> <label for="title" class="col-sm-2 control-label">書名</label> <div class="col-sm-10"> <input type="text" class="form-control w300" id="title" ng-model="book.title" /> </div> </div> <div class="form-group"> <label for="picture" class="col-sm-2 control-label">圖片</label> <div class="col-sm-10"> <input type="text" class="form-control w200" id="picture" ng-model="book.picture" /> </div> </div> <div class="form-group"> <label for="price" class="col-sm-2 control-label">價(jià)格</label> <div class="col-sm-10"> <input type="text" class="form-control w200" id="price" ng-model="book.price" /> </div> </div> <div class="form-group"> <label for="author" class="col-sm-2 control-label">作者</label> <div class="col-sm-10"> <input type="text" class="form-control w200" id="author" ng-model="book.author" /> </div> </div> </form> </div> <div class="modal-footer"> <button type="button" ng-click="save()" class="btn btn-primary"> <span class="glyphicon glyphicon-floppy-disk"></span> 保存</button> <button type="button" class="btn btn-success" ng-click="clear()" data-dismiss="modal"> <span class="glyphicon glyphicon-refresh"></span> 清空</button> <button type="button" class="btn btn-danger" data-dismiss="modal"> <span class="glyphicon glyphicon-remove"></span> 關(guān)閉</button> </div> </div> </div> </div> </div> <table class="table"> <thead> <tr> <th> 序號 </th> <th> 編號 </th> <th> 書名 </th> <th> 圖片 </th> <th> 價(jià)格 </th> <th> 作者 </th> <th> 操作 </th> </tr> </thead> <tbody> <tr ng-repeat="b in books" ng-class="{'info':$odd}"> <td> {{$index+1}} </td> <td> {{b.id}} </td> <td> {{b.title}} </td> <td> <img ng-src="img/{{b.picture}}" class="cover" /> </td> <td> {{b.price | number:1}} </td> <td> {{b.author}} </td> <td> <button type="button" class="btn btn-danger btn-xs" ng-click="del(b.id,$index)">刪除</button> <button href="#modal-container-234446" role="button" class="btn btn-xs btn-primary" data-toggle="modal" ng-click="edit(b)">編輯</button> </td> </tr> </tbody> </table> </div> </div> </div> <!--引入angularjs框架--> <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/bootstrap/dist/js/bootstrap.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定義模塊,指定依賴項(xiàng)為空 var bookApp = angular.module("bookApp", []); //定義控制器,指定控制器的名稱,$scope是全局對象 bookApp.controller("BookController", ['$scope', '$http', function($scope, $http) { $scope.books = []; $scope.save = function() { $http({ url: "http://127.0.0.1:3000/books/book", data: $scope.book, method: $scope.book.id ? "PUT" : "POST" }) .success(function(data, status, headers, config) { if($scope.book.id) { alert("修改成功"); } else { $scope.books.push(data); } }) .error(function(data, status, headers, config) { alert(status); }); } $scope.edit = function(b) { $scope.book = b; } $scope.clear = function() { $scope.book = {}; } //初始化加載 $http.get("http://127.0.0.1:3000/") .success(function(data, status, headers, config) { $scope.books = data; }) .error(function(data, status, headers, config) { alert(status); }); $scope.del = function(id, index) { $http.delete("http://127.0.0.1:3000/books/id/" + id) .success(function(data, status, headers, config) { $scope.books.splice(index, 1); }) .error(function(data, status, headers, config) { alert(status); }); } }]); </script> </body> </html>
運(yùn)行結(jié)果:
新書上架:
編輯圖書
添加成功后:
感謝各位的閱讀!關(guān)于“如何使用NodeJS+MongoDB+AngularJS+Bootstrap開發(fā)書店項(xiàng)目”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。