用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」。

下载后,最好进行一次病毒检查。虽然从经验来看,在官方网站上检测到病毒的情况并不常见,但为了谨慎起见。

我会继续进行安装。
这次只需要接受全部默认设置,所以没有什么困难的部分。

0001.png
0002.png
0003.png
0004.png
0005.png
0006.png
image.png

将数据库注册到MongoDB

1002.png
1003.png
1004.png
1006.png

即使在这个时机不登记数据,也可以在之后创建完成形的MEAN堆栈,并逐个注册数据,以再现“英雄之旅”的数据。

1008.png
1009.png

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框架。

广告
将在 10 秒后关闭
bannerAds