最近在學習MEAN棧開發,但google來的教程又太分散,有講express的, restful接口的,angular-resource設計的,就是沒有一整套mean下來的。而成熟的框架如meteor、meanio、meanjs又不太適合新手?。html
最後通過本身的實踐綜合各個教程搭建了這個簡單的mean應用,實現了基本的CRUD操做?。從後端nodejs到前端angularjs都只用到了其中最簡單最方便的模塊。若是你也對MEAN開發有興趣卻摸不着頭腦,能夠看看我是怎麼鏈接mean各個模塊的?。前端
live demo
源代碼倉庫
後端概覽Mongoose Restful Mlab Express Nodejs
前端概覽 Angularjs Angular-ui-router angular-resource Bootstrap
Mongodb + Express + Angularjs + Nodejs == MEAN
背景知識請點擊node
後端數據模型構建 model > movies.jsgit
後端路由 routes > movies.jsangularjs
數據庫鏈接及服務器啓動 app.jsgithub
restful Api設計 public > js > service.jsmongodb
前端路由 public > js > app.js數據庫
數據顯示模板 public > * .htmlexpress
若是你想跟着我寫一遍,下載 Nodejs ☺並在項目中安裝以下package.json
package.json以下,不保證其餘版本能正常運行json
"angular": "^1.5.9", "angular-resource": "^1.5.9", "angular-ui-router": "^0.3.2", "body-parser": "^1.13.3", "bootstrap": "^3.3.7", "express": "^4.13.3", "mongoose": "^4.0.1"
構建後端Api
1.在model > movies.js 下咱們先構建數據模型,咱們的模型只包含title(電影名字),director(導演),其餘的不關心?。
關於數據模型mongoose.Schema更多設置
var mongoose = require('mongoose'); var Schema = mongoose.Schema; var movieSchema = new Schema({ title: String, director: String }); module.exports = mongoose.model('Movie', movieSchema);
2.在routes > movies.js 中設計路由Api, 用到express, 還有上一步中的數據模型Movie。
var Movie = require('../model/movie'); var express = require('express'); //導入模塊,賦值給router var router = express.Router(); //設計路由 router.route('/movies') // 取得全部 movies .get(function(req, res) { Movie.find(function(err, movies){ if (err) { res.send(err); } res.json(movies); }); }) // 開始熟悉的CRUD? .post(function(req, res) { // 建立一個 movie var movie = new Movie(req.body); movie.save(function(err) { if (err) { res.send(err); } }) }); router.route('/movies/:id') // 讀取一個 movie .get(function(req, res) { Movie.findOne({_id: req.params.id}, function(err, movie) { if (err) { res.send(err); } res.json(movie); }); }) // 修改一個 movie .put(function(req, res) { Movie.findOne({_id: req.params.id}, function(err, movie) { if (err) { res.send(err); } for(prop in req.body){ movie[prop] = req.body[prop]; } movie.save(function(err) { if (err) { res.send(err); } }); }); }) .delete(function(req, res) { // 刪除一個 movie Movie.remove({ _id: req.params.id }, function(err, movie) { if (err) { res.send(err); } }); }); //最後導出路由 module.exports = router;
3.在app.js下鏈接數據庫,創建服務器。數據庫用mlab,畢竟免費500MB?
var express = require('express'); var bodyParser = require('body-parser'); var movies = require('./routes/movies'); var mongoose = require('mongoose'); var app = express(); app.use(express.static(__dirname + '')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); //data api path app.use(movies); //這個是個人mlab數據庫地址,其中mean是帳號密碼 var connectionString = 'mongodb://mean:mean@ds113668.mlab.com:13668/mean'; //鏈接數據庫 mongoose.connect(connectionString); var conn = mongoose.connection; //測試數據庫鏈接是否正常 // conn.on('error', console.error.bind(console, 'connection error')) // conn.once('open', function() { // console.log('database ready'); // }); //啓動服務器在localhost:8000運行 app.set('port', process.env.PORT || 8000); app.listen(app.get('port'), function() { console.log('your app is running on port 8000'); })
構建前端Api
1.在public > js > movies.js用$resource構建api
angular.module('App.service', []) .factory('Movie', function($resource) { var $url = '/movies/:id'; return $resource($url, {id: '@_id'}, { //由於$resource沒有update方法,咱們要本身構建一個 update: { method: 'PUT' } }); }) //window全局模態框,在刪除數據時會用到 .service('popupService', function($window) { this.showPopup = function(message) { return $window.confirm(message); } });
2.在public > js > app.js中開啓前端路由,咱們使用angular-ui-router這個模塊
//主模塊App,依賴有ui.router,ngResource和咱們在上一步定義的App.service服務 angular.module('App', ['ui.router', 'ngResource', 'App.service']) //開始配置路由和熟悉的CRUD? .config(function ($stateProvider) { $stateProvider.state('movies', { url: '/movies', templateUrl: 'public/movies.html', controller: function( $scope, $state, popupService, $window, Movie) { //取得全部 movies $scope.movies = Movie.query(); $scope.deleteMovie = function(movie) { if (popupService.showPopup('刪除?')) { //刪除一個 movie movie.$delete(); $window.location.href = ''; } }; } }) .state('newMovie', { url: '/movies/new', templateUrl: 'public/movie-add.html', controller: function($scope, $state, $stateParams, Movie) { $scope.movie = new Movie(); $scope.addMovie = function () { //建立一個 movie $scope.movie.$save(); $state.go('movies'); } } }) .state('viewMovie', { url: '/movies/:id/view', templateUrl: 'public/movie-view.html', controller: function($scope, $stateParams, Movie) { //讀取 一個movie $scope.movie = Movie.get({id: $stateParams.id}); } }) .state('editMovie', { url: '/movies/:id/edit', templateUrl: 'public/movie-edit.html', controller: function($scope, $state, $stateParams, Movie) { $scope.updateMovie = function() { //更新一個 movie $scope.movie.$update(); $state.go('movies') }; $scope.loadMovie = function() { $scope.movie = Movie.get({id: $stateParams.id}); }; $scope.loadMovie(); } }); }) //默認路由 .run(function($state) { $state.go('movies'); });
3.路由設計完畢就能夠寫模板了,在index.html引入各種模塊及樣式表
//index.html 部份內容 <div class="container"> <div class="row top-buffer"> <div class="col-md-8 col-xs-offset-2"> //ui-view是ui-router的顯示區域。咱們上一步定義的state裏的templateUrl都顯示在這裏 <div ui-view></div> </div> </div> </div>
在public下還有另外5個模板,_form.html主要負責CRUD中的C(movie-add.html)和U(movie-edit.html)。CU兩個模板都引用_form.html
//這個是U模板 movie-edit.html <form role="form" ng-submit="updateMovie()" class="form-horizontal"> <div ng-include="'public/_form.html'"></div> </form>
//這個是C模板 movie-add.html <form role="form" ng-submit="addMovie()" class="form-horizontal"> <div ng-include="'public/_form.html'"></div> </form>
R模板(movie-view.html)用於展現單個movie數據
剩下的D操做和movies列表共用一個模板movies.html
<a ui-sref="newMovie" class="btn-primary btn-lg nodecoration">Add New Movie</a> <table class="table movietable"> <tr> <td><h3>All Movies</h3></td> <td></td> </tr> <tr ng-repeat="movie in movies"> <td>{{movie.title}}</td> <td> <a class="btn btn-primary" ui-sref="viewMovie({id:movie._id})">View</a> <a class="btn btn-danger" ng-click="deleteMovie(movie)">Delete</a> </td> </tr> </table>
至此,這個App的全部構建工做已經完成。MEAN中每個模塊所包含的知識都很是龐大,這只是一個很是簡單的新手教程,咱們體驗了一把Javascript Stack,串聯前端後端,設計簡單的Api,連接數據庫,操做數據,顯示模板。
但願這個教程對你進擊Javascript Stack 有幫助?
部分學習資料
MEAN Stack Tutorial MongoDB ExpressJS AngularJS NodeJS
Build a blog with the MEAN stack
Creating RESTful APIs with Express 4
Creating a CRUD App in Minutes with Angular’s $resource