Docs 菜单
Docs 主页
/ /

将MongoDB与Angular集成

在本指南中,您可以学习;了解如何创建使用MEAN堆栈的Angular Web应用程序。 MEAN堆栈是一个 Web 开发框架,使用MongoDB、 Express、 Angular和 Node.js ,由以下各层组成:

  • 数据库层:MongoDB提供数据存储和检索。

  • 应用程序层: Express和 节点.js 构成服务器端逻辑的中间层级。

  • 表示层: Angular实现用户界面和前端交互。

Angular是一个用于创建动态 Web 应用程序的 TypeScript框架。它为范围应用程序功能提供了内置包,其基于组件的架构使应用程序具有高度可重用性。

由于 TypeScript 基于JavaScript构建,因此MEAN堆栈的每个元素都基于JavaScript和JSON。因此,这些元素之间的集成非常简单。 Angular前端创建JSON文档, MongoDB可以直接将其存储为BSON格式(一种二进制JSON扩展),而Express提供了使用JavaScript 的极简框架。 MongoDB为BSON文档提供高级索引和查询功能,并包含原生Node.js驾驶员,这使其成为JavaScript应用程序的理想数据存储。

本教程向您展示如何使用MEAN堆栈构建Web应用程序。该应用程序访问示例餐厅数据,查询数据,并在本地托管站点上显示结果。本教程还包括有关连接到MongoDB Atlas上托管的MongoDB 集群以及访问和显示数据库数据的说明。

提示

如果您更愿意使用 Node.js驾驶员而不是Angular连接到MongoDB ,请参阅 Node.js驱动程序程序入门指南。

按照本节中的步骤安装项目依赖项、创建Atlas集群并设立应用程序目录。

1

要创建快速入门应用程序,请在开发环境中安装以下软件:

先决条件
注意

下载最新 LTS最新版本

通过在终端中运行npm install -g @angular/cli 进行全局安装。

代码编辑器

使用您选择的编辑器。

终端应用和shell

对于 MacOS 用户,请使用终端或类似应用程序。对于 Windows 用户,请使用 PowerShell。

2

MongoDB Atlas是一项完全托管云数据库服务,用于托管MongoDB部署。如果您没有MongoDB 部署,可以通过完成MongoDB入门教程来免费创建MongoDB 集群。 MongoDB入门教程还演示了如何将示例数据集加载到集群中,包括本教程中使用的sample_restaurants 数据库。

要连接到MongoDB集群,您必须使用连接 URI。学习如何检索连接 URI,请参阅MongoDB入门教程的添加连接字符串部分。

重要

将连接string保存在安全位置。

3

在终端中运行以下命令,为项目创建一个名为 angular-quickstart 的目录:

mkdir angular-quickstart
cd angular-quickstart

然后,从 angular-quickstart目录运行以下命令,为后端创建一个名为 server 的文件夹并初始化 package.json文件:

mkdir server
cd server
npm init -y
4

导航到 angular-quickstart/server目录中的 package.json文件。要使用 ECMAScript 模块,打包 JavaScript 代码以供重复使用的标准格式,请将指定 "type" 字段的现有行替换为以下行:

"type": "module",
5

运行以下命令以安装 mongodbexpresscorsdotenv 依赖项:

npm install mongodb express cors dotenv

此命令会安装MongoDB、 Express Web框架、用于跨域资源共享的 cors Node.js包以及用于加载环境变量的 Dotenv。

接下来,运行以下命令以安装 TypeScript 和所需的类型定义:

npm install typescript @types/node @types/express tsx

此命令会安装 TypeScript、Node.js 和Express的类型定义以及 tsx(用于直接运行TypeScript 文件的工具)。

设置项目结构和依赖项后,请按照本节中的步骤配置 Web服务器并连接到MongoDB。

1

angular-quickstart/server目录中创建名为 server.ts 的文件并粘贴以下代码:

Angular-quickstart/ 服务器/ 服务器.ts
import express from "express";
import cors from "cors";
import restaurants from "./routes/restaurant.js";
const PORT = process.env.PORT || 5050;
const app = express();
app.use(cors());
app.use(express.json());
app.use("/restaurant", restaurants);
// start the Express server
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});
2

server目录中,创建 .env文件并粘贴以下代码:

MONGODB_URI=<connection string>
PORT=5050

<connection string> 占位符替换为您在上一步中保存的连接字符串。

3

server目录中,创建一个名为 db 的子目录。在此子目录中添加一个名为 connection.ts 的新文件,并粘贴以下代码:

Angular-quickstart/ 服务器/db/connection.ts
import "dotenv/config";
import { MongoClient, Db } from "mongodb";
const uri = process.env.MONGODB_URI || "";
const client = new MongoClient(uri);
try {
// Connects the client to the server
await client.connect();
// Sends a ping to confirm a successful connection
await client.db("admin").command({ ping: 1 });
console.log(
"Pinged your deployment. You successfully connected to MongoDB!"
);
} catch(err) {
console.error(err);
}
const db: Db = client.db("sample_restaurants");
export default db;

此文件连接到MongoDB 部署、访问 sample_restaurants数据库并测试数据库连接。

4

server目录中,创建一个名为 routes 的子目录。在此子目录中创建名为 restaurant.ts 的文件并粘贴以下代码:

Angular-quickstart/ 服务器/routes/restaurant.ts
import express, { Request, Response } from "express";
import db from "../db/connection.js";
// Creates an instance of the Express router, used to define our routes
const router = express.Router();
// Gets a list of all the restaurants
router.get("/", async (req: Request, res: Response) => {
let collection = await db.collection("restaurants");
let results = await collection.find({}).toArray();
res.send(results).status(200);
});
// Lists restaurants that match the query filter
router.get("/browse", async (req: Request, res: Response) => {
try {
let collection = await db.collection("restaurants");
let query = {
borough: "Queens",
name: { $regex: "Moon", $options: "i" },
};
let results = await collection.find(query).toArray();
res.send(results).status(200);
} catch (err) {
console.error(err);
res.status(500).send("Error browsing restaurants");
}
});
export default router;

此文件访问 sample_restaurants数据库中的 restaurants集合并定义以下 GET 终结点:

  • /:从示例集合中检索所有餐厅

  • /browse:检索符合查询条件的餐厅,该条件过滤器出位于皇后区且名称中包含 "Moon" 一词的餐厅

设置应用程序的后端后,请按照本节中的步骤配置Angular并添加前端组件。

1

导航到 angular-quickstart目录并运行以下命令以创建新的Angular应用程序:

ng new client

此命令会提示您回答一系列配置问题。对于每个问题,请根据以下指导选择适当的答案:

  • 想要启用自动完成功能?:输入 Y N

  • 是否愿意股票假名使用数据?:输入 Y N

  • 您想使用哪种样式表系统?选择 Tailwind CSS

  • 是否要启用服务器端渲染 (SSR) 和静态站点生成(SSG/预渲染)?输入 Y N

  • 您希望使用Angular最佳实践来配置哪些AI工具?选择您喜欢的工具

运行该命令后,您的项目将出现一个包含前端脚手架的 client目录。该命令还会将项目配置为使用 TailwindCSS,这是一个用于用户界面格式化的框架。

2

从客户端目录运行以下命令以安装 Zone.js:

npm install zone.js

您的应用程序使用 Zone.js 库跟踪更改并自动更新用户界面。

3

client目录中,运行以下命令以生成处理对后端的API调用的服务:

ng generate service restaurant

导航到 client/src/app/restaurant.ts文件并将内容替换为以下代码:

Angular-quickstart/ 客户端/src/ 应用/restaurant.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
export interface Restaurant {
_id: string;
name: string;
borough: string;
cuisine: string;
}
@Injectable({
providedIn: 'root'
})
export class RestaurantService {
private apiUrl = 'http://localhost:5050/restaurant';
constructor(private http: HttpClient) {}
getAllRestaurants(): Observable<Restaurant[]> {
return this.http.get<Restaurant[]>(this.apiUrl);
}
getFilteredRestaurants(): Observable<Restaurant[]> {
return this.http.get<Restaurant[]>(`${this.apiUrl}/browse`);
}
}

此服务定义了从Express API获取餐厅数据的方法。

4

导航到 client/src/app/app.routes.ts文件并将内容替换为以下代码:

Angular-quickstart/ 客户端/src/ 应用/ 应用.routes.ts
import { Routes } from '@angular/router';
import { RestaurantListComponent } from './restaurant-list/restaurant-list';
export const routes: Routes = [
{ path: '', component: RestaurantListComponent },
{ path: 'browse', component: RestaurantListComponent }
];

此文件配置客户端路由并定义以下路由:

  • /:显示来自 /restaurant/ API端点的所有餐厅

  • /browse:显示从 /restaurant/browse API端点筛选的餐厅

5

导航到 client/src/app/app.config.ts文件并将内容替换为以下代码:

Angular-quickstart/ 客户端/src/ 应用/ 应用.config.ts
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideHttpClient()
]
};

此配置启用用于发出API请求的HTTP客户端功能。

6

client目录运行以下命令,生成用于显示餐厅的组件:

ng generate component restaurant-list

导航到 client/src/app/restaurant-list/restaurant-list.ts文件并将内容替换为以下代码:

Angular-quickstart/ 客户端/src/ 应用/restaurant-list/restaurant-list.ts
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Router } from '@angular/router';
import { RestaurantService, Restaurant } from '../restaurant';
@Component({
selector: 'app-restaurant-list',
standalone: true,
imports: [CommonModule],
templateUrl: './restaurant-list.html',
styleUrl: './restaurant-list.css'
})
export class RestaurantListComponent implements OnInit {
restaurants: Restaurant[] = [];
loading = true;
error = '';
constructor(
private restaurantService: RestaurantService,
public router: Router
) {}
ngOnInit(): void {
this.loadRestaurants();
}
loadRestaurants(): void {
const isFiltered = this.router.url === '/browse';
const observable = isFiltered
? this.restaurantService.getFilteredRestaurants()
: this.restaurantService.getAllRestaurants();
observable.subscribe({
next: (data) => {
this.restaurants = data;
this.loading = false;
},
error: (err) => {
this.error = 'Failed to load restaurants';
this.loading = false;
console.error('Error loading restaurants:', err);
}
});
}
}

然后,导航到 client/src/app/restaurant-list/restaurant-list.html文件并将内容替换为以下代码:

Angular-quickstart/ 客户端/src/ 应用/restaurant-list/restaurant-list.html
<div *ngIf="loading" class="text-center py-8">
<p class="text-gray-600">Loading restaurants...</p>
</div>
<div *ngIf="error" class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
{{ error }}
</div>
<div *ngIf="!loading && !error">
<h3 class="text-lg font-semibold p-4">
{{ router.url === '/browse' ? 'Filtered Restaurants (Queens, containing "Moon")' : 'All Restaurants' }}
</h3>
<div class="border rounded-lg overflow-hidden">
<div class="relative w-full overflow-auto">
<table class="w-full caption-bottom text-sm">
<thead class="[&_tr]:border-b">
<tr class="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted">
<th class="h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0">
Name
</th>
<th class="h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0">
Borough
</th>
<th class="h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0">
Cuisine
</th>
</tr>
</thead>
<tbody class="[&_tr:last-child]:border-0">
<tr *ngFor="let restaurant of restaurants" class="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted">
<td class="p-4 align-middle [&:has([role=checkbox])]:pr-0">
{{ restaurant.name }}
</td>
<td class="p-4 align-middle [&:has([role=checkbox])]:pr-0">
{{ restaurant.borough }}
</td>
<td class="p-4 align-middle [&:has([role=checkbox])]:pr-0">
{{ restaurant.cuisine }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

该组件根据当前路线检索并显示餐厅信息。

7

导航到 client/src/app/app.ts文件并将内容替换为以下代码:

Angular-quickstart/ 客户端/src/ 应用/ 应用.ts
import { Component } from '@angular/core';
import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, RouterLink, RouterLinkActive],
templateUrl: './app.html',
styleUrl: './app.css'
})
export class AppComponent {
title = 'Restaurant Browser';
}

然后,导航到 client/src/app/app.html文件并将内容替换为以下代码:

angular-quickstart/client/src/app/app.html
<div class="w-full p-6">
<nav class="flex justify-between items-center mb-6">
<a routerLink="/">
<img
alt="MongoDB logo"
class="h-10 inline"
src="https://d3cy9zhslanhfa.cloudfront.net/media/3800C044-6298-4575-A05D5C6B7623EE37/4B45D0EC-3482-4759-82DA37D8EA07D229/webimage-8A27671A-8A53-45DC-89D7BF8537F15A0D.png"
/>
</a>
<div class="flex gap-4">
<a routerLink="/" routerLinkActive="font-bold" [routerLinkActiveOptions]="{exact: true}" class="text-blue-600 hover:underline">
All Restaurants
</a>
<a routerLink="/browse" routerLinkActive="font-bold" class="text-blue-600 hover:underline">
Filtered Restaurants
</a>
</div>
</nav>
<router-outlet></router-outlet>
</div>

这是主要的应用程序组件,其中包括导航并根据当前路由呈现相应的子组件。

8

导航到 client/src/main.ts文件并将内容替换为以下代码:

Angular-quickstart/ 客户端/src/main.ts
import 'zone.js';
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app';
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));

此文件充当应用程序的入口点,并应用和呈现您的配置。

最后,按照本节中的步骤运行应用程序并查看呈现的餐厅数据。

1

server目录中运行以下命令以启动服务器:

npx tsx server.ts

如果成功,此命令将输出以下信息:

Pinged your deployment. You successfully connected to MongoDB!
Server listening on port 5050
2

在另一个终端窗口中,导航到 client目录。运行以下命令以启动Angular前端:

ng serve

如果成功,此命令将输出以下信息:

Application bundle generation complete.
Watch mode enabled. Watching for file changes...
NOTE: Raw file sizes do not reflect development server per-request transformations.
➜ Local: http://localhost:4200/
➜ press h + enter to show help

您的Angular应用程序从端口 4200 向端口 5050 发出HTTP请求以检索数据。

3

打开 http://localhost:4200 / URL。初始登陆页面显示sample_restaurants.restaurants 集合中所有餐厅的列表:

显示所有餐厅的登陆页面

然后,单击导航栏中的 Filtered Restaurants 链接,查看与 nameborough字段查询匹配的餐厅:

显示匹配餐厅的网页

恭喜您完成快速入门教程!

完成这些步骤后,您就拥有了一个Angular Web应用程序,它可以连接到您的MongoDB 部署、对示例餐厅数据运行查询,并在本地托管的网站上呈现结果。

要学习;了解有关Angular、 MongoDB和MEAN堆栈的更多信息,请查看以下资源:

后退

问题与帮助

在此页面上