我是如何用MEAN栈来搭建一个简单的App的
最近在学习MEAN栈开发,但google来的教程又太分散,有讲express的, restful接口的,angular-resource设计的,就是没有一整套mean下来的。而成熟的框架如meteor、meanio、meanjs又不太适合新手?。
最后经过自己的实践综合各个教程搭建了这个简单的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
背景知识请点击
目录结构如下图
后端搭建
后端数据模型构建 model > movies.js
后端路由 routes > movies.js
数据库连接及服务器启动 app.js
前端搭建
restful Api设计 public > js > service.js
前端路由 public > js > app.js
数据显示模板 public > * .html
如果你想跟着我写一遍,下载 Nodejs ☺并在项目中安装如下package.json
package.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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。