MEAN Stack (Angular5) CRUD Web Application Example

Introduction

这篇文章我们接着学习Angular5, NodeJs Create-Read-Update-Delete(CRUD) web应用, 其中还会用到MongoDB, Mongo daemon.

1. Update Angular CLI and Create Angular5 Application

之前的博客中已经介绍了, 具体指令如下

1
2
3
4
sudo npm install -g @angular/cli
ng new mean-angular5
cd mean-angular5
ng server -o

alt text

2. Replace Web Server with Express.js

step1

首先关掉运行中的项目,输入’ctrl+c’, 然后安装Express.js 组件

1
npm install --save express body-parser morgan body-parser serve-favicon

step2

创建bin文件夹, 并加入www文件

1
2
mkdir bin
touch bin/www

打开并编辑www文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env node

/**
* Module dependencies.
*/

var app = require('../app');
var debug = require('debug')('mean-app:server');
var http = require('http');

/**
* Get port from environment and store in Express.
*/

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
* Create HTTP server.
*/

var server = http.createServer(app);

/**
* Listen on provided port, on all network interfaces.
*/

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
* Normalize a port into a number, string, or false.
*/

function normalizePort(val) {
var port = parseInt(val, 10);

if (isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// port number
return port;
}

return false;
}

/**
* Event listener for HTTP server "error" event.
*/

function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}

var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;

// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}

/**
* Event listener for HTTP server "listening" event.
*/

function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

step3

打开并编辑”package.json”, 替换”start”, 这样可以让server在运行时先运行www文件

1
2
3
4
5
6
7
8
"scripts": {
"ng": "ng",
"start": "ng build && node ./bin/www",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},

step3

在根目录创建app.js

1
touch app.js

打开并编辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');

var book = require('./routes/book');
var app = express();

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({'extended':'false'}));
app.use(express.static(path.join(__dirname, 'dist')));
app.use('/books', express.static(path.join(__dirname, 'dist')));
app.use('/book', book);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});

// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
res.status(err.status || 500);
res.render('error');
});

module.exports = app;

step4

接下来创建routes文件夹, 并创建book的路径

1
2
mkdir routes
touch routes/book.js

编辑book.js

1
2
3
4
5
6
7
8
9
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function (req, res, next) {
res.send('Express RESTful API');
});

module.exports = router;

现在可以运行项目了, 输入网址 ‘http://localhost:3000/book'

1
npm start

alt text

4. Install and Configure Mongoose.js

我们将会用到MongoDB, 现在我们来学习如何安装和配置Mongoose.js

1
npm install --save mongoose bluebird

编辑 app.js

1
2
3
4
5
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost/mean-angular5', { useMongoClient: true, promiseLibrary: require('bluebird')})
.then(() => console.log('connection succesful'))
.catch((err) => console.error(err));

5. Create Mongoose.js Model

在跟目录中创建models文件夹, 并且创建一个Book collection

1
2
mkdir models
touch models/Books.js

打开Books.js 编辑

1
2
3
4
5
6
7
8
9
10
11
var mongoose = require('mongoose');
var BookSchema = new mongoose.Schema({
isbn: String,
title: String,
author: String,
description: String,
published_year: String,
publisher: String,
updated_date: { type: Date, default: Date.now },
});
module.export = mongoose.model('Book', BookSchema);

To be continue…