基於Nodejs+express4+Mongodb+Angularjs建立web項目 基於Nodejs搭建web伺服器 利用Express4搭建restful服務 使用Mongodb作為資料庫,用mongoose元件連線Mongodb 使用AngularJS+bootstrap設計UI介面 使用Webstorm 10.0.4開發
第一部分:服務端搭建
1.通過Webstorm建立Node.js Express APP
File -> New Project -> Node.js Express App, Location欄填寫項目名稱,選擇Nodejs和npm位置, Options -> Template 選擇EJS
在項目下建立檔案夾models儲存mongodb相關對應model。
在models目錄下建立model檔案movie.js。
在routes目錄下建立restful API 支援檔案 movies.js
完成後的目錄結構如下
- project -- bin --- www -- models --- movie.js -- node_modules --- ... -- public --- ... -- routes movies.js app.js package.json
2.在package.json中添加mongoose支援及其他相關組件
{ "name": "project", "version": "0.0.0", "private": true, "scripts": { "start": "node ./bin/www" }, "dependencies": { "body-parser": "~1.13.2", "cookie-parser": "~1.3.5", "debug": "~2.2.0", "ejs": "~2.3.3", "express": "~4.13.1", "morgan": "~1.6.1", "errorhandler": "~1.4.2", "serve-favicon": "~2.3.0", "mongoose": "~4.2.5", "connect-mongo": "latest", "express-session": "latest" }, "engines": { "node": ">=0.10.0" }}
3.在movie.js中建立movie模型:
var mongoose = require('mongoose');var Schema = mongoose.Schema;// define an db objectvar movieSchema = new Schema({ title: String, releaseYear: String, director: String, genre: String});// bind module for accessing outsidemodule.exports = mongoose.model('Movie', movieSchema);
4.在movies.js中建立基於movie的restful API
引入movie模型,並開啟router
var Movie = require('../models/movie.js');var express = require('express');var router = express.Router();
實現一些基本的功能API
var Movie = require('../models/movie.js');// get all moviesexports.list = function(req, res){ Movie.find(function (err, movies) { if (err) { return res.send(err); } res.json(movies); })};// create new movieexports.create = function(req, res){ var movie = new Movie(req.body); movie.save(function (err) { if (err) { return res.send(err); } res.send({message: 'add a movie'}); });};// update a movieexports.update = function (req, res) { //Movie.findById(req.params.id, callback) Movie.findOne({_id: req.params.id}, function (err, movie) { if (err) { return res.send(err); } for (prop in req.body) { movie[prop] = req.body[prop]; } movie.save(function (err) { if (err) { return res.send(err); } res.json({message: "update a movie"}); }); });};//delete a movieexports.delete = function (req, res) { Movie.remove({_id: req.params.id}, function (err, movie) { if (err) { return res.send(err); } res.json({message: 'delete a movie'}); });};
匯出功能模組讓其他部分可以使用該模組
module.exports = router;
5.啟用Restful服務
在app.js中引入mongoose建立資料庫連接
var mongoose = require('mongoose');// connect to mongodbvar dbName = 'movie';var url = 'mongodb://localhost:27017/' + dbName;var mongoOptions = { server: { socketOptions: { keepAlive: 1 } }};mongoose.connect(url, mongoOptions);mongoose.connection.on('error', function (err) { console.log('Mongo Error:' + err);}).on('open', function () { console.log('Connection opened');});
引入router啟用Restful服務
var express = require('express');var app = express();var movies = require('./routes/movies');app.use('/api', movies);
由於http通訊是基於json格式的,需要指定請求資料格式和編碼
var bodyParser = require('body-parser');app.use(bodyParser.json());app.use(bodyParser.urlencoded({extended: false}));
匯出模組
module.exports = app;
6.在bin/www中開啟server
var app = require('../app');var http = require('http');var port = normalizePort(process.env.PORT || '3000');app.set('port', port);//Create HTTP servervar server = http.createServer(app);server.listen(port);
運行 bin/www (node bin/www)即可運行伺服器。 第二部分:前端搭建
前端使用AngularJS+Bootstrap搭建 1.引入bower
先安裝NodeJS,使用npm工具引入bower。
在專案檔夾pubic下依次建立以下目錄結構
- project -- ... -- public --- css --- images --- js ---- controller ---- service --- views index.html
添加bower依賴,在項目根目錄下建立.bowerrc檔案,指定bower安裝路徑
{ "directory": "/public/bower_components"}
添加bower.json檔案指定依賴:
{ "name": "project", "version": "0.0.0", "dependencies": { "jquery": "~2.1.3", "bootstrap": "~3.3.2", "angular": "~1.3.8", "font-awesome": "~4.2.0", "angular-ui-router": "~0.2.13", "angular-bootstrap": "~0.12.1" }}
運行bower install,安裝相關js外掛程式 2.引入AngularJS組件
在public > js下建立module.js,建立AngularJS項目組件app
'use strict';var app = angular.module('app', [ 'ui.router', 'ui.bootstrap']);
建立一個service來儲存windows session
session.storage.js
(function (app) { 'use strict'; app.factory('SessionStorage', function ($window) { var store = $window.sessionStorage; return { save: function (key, value) { value = angular.toJson(value); store.setItem(key, value); }, get: function (key) { var value = store.getItem(key); if (value) { value = angular.fromJson(value); } return value; }, delete: function (key) { store.removeItem(key); } } });})(angular.module('app'));
建立一個movie service進行http請求
movie.service.js
(function (app) { 'use strict'; app.factory('MovieService', function ($http, $q) { return { getAllMovies: function () { var url = "http://localhost:3000/api/movie/all"; var deferred = $q.defer(); $http.get(url).then( function success(respData) { var movies = respData.data; deferred.resolve(movies); }, function error(reason) { deferred.reject(reason); } ); return deferred.promise; }, updateMovie: function (movie, id) { var url = "http://localhost:3000/api/movie/" + id; var deferred = $q.defer(); $http.put(url, movie).then( function success(respData) { var movies = respData.data; deferred.resolve(movies); }, function error(reason) { deferred.reject(reason); } ); return deferred.promise; } } });})(angular.module('app'));
在controller目錄下建立兩個controller處理相關資料操作
main.controller.js
(function (app) { 'use strict'; app.controller('MainController', function ($scope, $rootScope, $state, SessionStorage, movies) { $rootScope.title = 'express_demo2'; $scope.movies = movies; $scope.updateMovie = function (movie) { SessionStorage.delete('movie'); $state.go('movie.update', {data: movie}); }; });})(angular.module('app'));
movie.controller.js
(function (app) { 'use strict'; app.controller('MovieController', function ($scope, $rootScope, $state, $stateParams, MovieService, SessionStorage) { $scope.movie = $stateParams.data; if (!$scope.movie) { $scope.movie = SessionStorage.get('movie'); } else { SessionStorage.save('movie', $scope.movie); } $scope.update = function () { var promise = MovieService.updateMovie($scope.movie, $scope.movie._id); promise.then(function (data) { alert('update success!'); SessionStorage.delete('movie'); $state.go('movie.main'); }); }; });})(angular.module('app'));
建立uirouter指定路由
(function (app) { 'use strict'; app.config(function ($stateProvider, $urlRouterProvider, $locationProvider) { $locationProvider.html5Mode(true); $urlRouterProvider.otherwise('/movie'); $stateProvider .state('movie', { abstract: 'true', templateUrl: '/views/menu.html' }) .state('movie.main', { url: '/movie', controller: 'MainController', templateUrl: '/views/main.html', resolve: { 'movies': function (MovieService) { return MovieService.getAllMovies(); } } }) .state('movie.update', { url: '/movie/update', controller: 'MovieController', templateUrl: '/views/update.html', params: { data: null } }); });})(angular.module('app'));
在css檔案下建立css
.margin-top-20 { margin-top: 20px;}.title-font { font-size: large; font-style: italic; font-family: Consolas; font-weight: bold;}
在index.html中聲明app位置,並匯入相關的js和css檔案
<!DOCTYPE html><html ng-app="app"><head> <meta charset="UTF-8"/> <base href='/'/> <title ng-bind="title"></title> <link rel='stylesheet' href='bower_components/bootstrap/dist/css/bootstrap.css'/> <link rel='stylesheet' href='bower_components/font-awesome/css/font-awesome.css'/> <link rel='stylesheet' href='css/style.css'/></head><body><div ui-view></div><script src="bower_components/jquery/dist/jquery.min.js"></script><script src="bower_components/angular/angular.min.js"></script><script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script><script src="bower_components/angular-ui-router/release/angular-ui-router.min.js"></script><script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script><script src="js/module.js"></script><script src="js/routes.js"></script><script src="js/controller/main.controller.js"></script><script src="js/controller/movie.controller.js"></script><script src="js/service/movie.service.js"></script><script src="js/service/session.storag