用Angular的“英雄之旅”使用MEAN堆栈
首先
上一篇文章提到了MEAN技术栈的简要介绍。现在我们继续讨论Angular和Express的协作。
我们将把Angular官方教程’Tour of Heroes’转化为MEAN技术栈的形式。
上次,我进行了一些对从Angular官方下载下来的“英雄之旅”进行修改,使其能够访问实际的服务器。
然后,我建立了一个Express服务器。
但是,我没有使用数据库,只是在服务器内部作为一个数组来保存英雄列表。
本次是在Windows环境下,我想要安装并设置MongoDB,以完成MEAN中的“M”部分。
安装MongoDB
首先,您需要下载MongoDB。您可以在MongoDB官网的「Available Downloads」页面中注册并提供必要的环境信息,然后点击「Download」进行下载。您将获取到安装包。我使用的安装包文件名为「mongodb-win32-x86_64-2012plus-4.2.7-signed.msi」。
下载后,最好进行一次病毒检查。虽然从经验来看,在官方网站上检测到病毒的情况并不常见,但为了谨慎起见。
我会继续进行安装。
这次只需要接受全部默认设置,所以没有什么困难的部分。
将数据库注册到MongoDB
即使在这个时机不登记数据,也可以在之后创建完成形的MEAN堆栈,并逐个注册数据,以再现“英雄之旅”的数据。
Express 对MongoDB的支持
首先,在Node中访问MongoDB,需要添加mongoose模块。
在命令提示符中切换到项目的目录下,
D:\angular\toh-srv>npm install mongoose
作为一个选项,将mongoose添加到服务器程序中。
接下来,我们将修改源文件。
为了与MongoDB中注册的数据库对应,我们将定义模型。
在上一篇文章关于MEAN堆栈前进一步之前,我们将在Angular和Express的连接源文件中
添加model.js文件。
const mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/heroes");
const HeroesModelSchema = new mongoose.Schema({
id: Number,
name: String
});
module.exports = mongoose.model('heroes', HeroesModelSchema);
这个时候,
mongoose.connect("mongodb://localhost/heroes");
「heroes」能够对应MongoDB中已注册的数据库名称为「Database Name」。
接下来,我们将继续修正服务器的主要程序。
const express = require('express'); // expressモジュールを読み込む
const bodyParser = require('body-parser'); // body-parserモジュールを読み込む
const multer = require('multer'); // multerモジュールを読み込む
var HeroesModel = require('./model');
const app = express(); // expressアプリを生成する
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// heroes リストデータ
/*const heroes = [
{ id: 11, name: 'Dr Nice' },
{ id: 12, name: 'Narco' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' },
{ id: 16, name: 'RubberMan' },
{ id: 17, name: 'Dynama' },
{ id: 18, name: 'Dr IQ' },
{ id: 19, name: 'Magma' },
{ id: 20, name: 'Tornado' }
];
//*/
// 新しいヒーローIDを作成.
function genId(){
return new Promise(function (resolve, reject){
HeroesModel.find().sort({id:-1}).limit(1).exec({}, function(err, heroes){
if(err) return handleError(err);
if(heroes.length>0) resolve(heroes[0].id + 1);
else resolve(11);
});
});
}
// ヒーローのリストを取得
app.get('/heroes', (req, res) => {
console.log('@@ get heroes');
if(req.query.name)
{
// req.query.name を含むヒーローのリストを作成して返す.
const query_name = req.query.name;
HeroesModel.find( { "name" : new RegExp( ".*"+query_name+".*") } ).select('id name').exec({}, function(err, heroes){
if(err) return handleError(err);
res.json(heroes);
});
}else{
HeroesModel.find().select('id name').exec({}, function(err, heroes){
if(err) return handleError(err);
res.json(heroes);
});
}
});
// idを指定してヒーローを取得
app.get('/heroes/:id', (req, res) => {
const query_id = req.params.id;
console.log('@@ get heroes id:' + query_id);
HeroesModel.find( { "id" : query_id } ).select('id name').exec({}, function(err, heroes){
if(err) return handleError(err);
if(heroes.length<=0)res.sendStatus(404);
res.json(heroes[0]);
});
});
// 新しいヒーローを登録
app.post('/heroes', (req, res) => {
const query_name = req.body.name;
console.log('@@post heroes :' + query_name);
genId().then(function(newId){
console.log(newId);
var heroes = new HeroesModel({
id: newId,
name: query_name
});
heroes.save(function(err){
if(err) return handleError(err);
// 追加した項目をクライアントに返す
res.json(heroes);
});
}).catch(function (error) {
// 非同期処理失敗。呼ばれない
console.log('catch err :' );
console.log(error);
});
});
// ヒーロー削除
app.delete('/heroes/:id', (req, res) => {
const query_id = req.params.id;
console.log('@@delete heroes id:' + query_id);
HeroesModel.remove( { "id" : query_id }, function(err){
if(err) return handleError(err);
// ステータスコード200:OKを送信
res.sendStatus(200);
});
});
// ヒーロー名修正
app.put('/heroes', (req, res) => {
// URLの:idと同じIDを持つ項目を検索
const query_id = req.body.id;
const query_name = req.body.name;
console.log('@@put heroes / req.body:' + query_id);
console.log('@@put heroes / req.body:' + query_name);
HeroesModel.update( { "id" : query_id }, {$set: { name: query_name}} ).select('id name').exec({}, function(err){
if(err) return handleError(err);
// ステータスコード200:OKを送信
res.sendStatus(200);
});
});
// ポート3000でサーバを立てる
app.listen(3000, () => console.log('Listening on port 3000'));
我正在导入之前定义的模型。
而是将heroes列表数据注释掉了。
可以删除这部分。
通过使用 genId 函数来创建新的英雄 ID,同时在每个 get、post、delete、put 部分中,代码被替换为与 MongoDB 相对应的代码。尤其是在 post 部分使用 genId 时遇到了一些困难。由于对 Promise 的理解不够,我重新学习了 MDN 上的 Express Web Framework (Node.js/JavaScript) 的基础知识。
考试
好了,现在完成了。只需要启动服务器和客户端,我认为我们就可以恢复’Tour of Heroes’的原始状态了。
结束
我觉得它大致上可以算是MEAN栈了。
然而,如果想要构建一个正式的Web应用程序,我觉得还有很多事情要做。
接下来能否进行一些改进…就看我的动力了(^^ゞ
链接
除了Express,Web开发的字母表里还有很多内容。Express是一个基于Node.js和JavaScript的Web框架。