Overview
在本指南中,您可以学习;了解如何创建使用MEAN堆栈的Angular Web应用程序。 MEAN堆栈是一个 Web 开发框架,使用MongoDB、 Express、 Angular和 Node.js ,由以下各层组成:
数据库层:MongoDB提供数据存储和检索。
应用程序层: Express和 节点.js 构成服务器端逻辑的中间层级。
表示层: Angular实现用户界面和前端交互。
为何在Angular应用程序中使用MongoDB ?
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集群并设立应用程序目录。
创建MongoDB Atlas 群集。
MongoDB Atlas是一项完全托管云数据库服务,用于托管MongoDB部署。如果您没有MongoDB 部署,可以通过完成MongoDB入门教程来免费创建MongoDB 集群。 MongoDB入门教程还演示了如何将示例数据集加载到集群中,包括本教程中使用的sample_restaurants 数据库。
要连接到MongoDB集群,您必须使用连接 URI。学习如何检索连接 URI,请参阅MongoDB入门教程的添加连接字符串部分。
重要
将连接string保存在安全位置。
修改package.json 文件。
导航到 angular-quickstart/server目录中的 package.json文件。要使用 ECMAScript 模块,打包 JavaScript 代码以供重复使用的标准格式,请将指定 "type" 字段的现有行替换为以下行:
"type": "module",
安装依赖项。
运行以下命令以安装 mongodb、express、cors 和 dotenv 依赖项:
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。
配置Express Web服务器。
在 angular-quickstart/server目录中创建名为 server.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}`); });
设置环境变量。
在 server目录中,创建 .env文件并粘贴以下代码:
MONGODB_URI=<connection string> PORT=5050
将<connection string> 占位符替换为您在上一步中保存的连接字符串。
将服务器连接到数据库。
在 server目录中,创建一个名为 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数据库并测试数据库连接。
创建服务器API端点。
在 server目录中,创建一个名为 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并添加前端组件。
创建Angular应用程序。
导航到 angular-quickstart目录并运行以下命令以创建新的Angular应用程序:
ng new client
此命令会提示您回答一系列配置问题。对于每个问题,请根据以下指导选择适当的答案:
想要启用自动完成功能?:输入 Y 或 N
是否愿意股票假名使用数据?:输入 Y 或 N
您想使用哪种样式表系统?选择 Tailwind CSS
是否要启用服务器端渲染 (SSR) 和静态站点生成(SSG/预渲染)?输入 Y 或 N
您希望使用Angular最佳实践来配置哪些AI工具?选择您喜欢的工具
运行该命令后,您的项目将出现一个包含前端脚手架的 client目录。该命令还会将项目配置为使用 TailwindCSS,这是一个用于用户界面格式化的框架。
创建餐厅服务。
在 client目录中,运行以下命令以生成处理对后端的API调用的服务:
ng generate service restaurant
导航到 client/src/app/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; } ({ 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获取餐厅数据的方法。
配置路由。
导航到 client/src/app/app.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/browseAPI端点筛选的餐厅
更新应用程序配置。
导航到 client/src/app/app.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客户端功能。
创建餐厅列表组件。
从 client目录运行以下命令,生成用于显示餐厅的组件:
ng generate component restaurant-list
导航到 client/src/app/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'; ({ 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文件并将内容替换为以下代码:
<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>
该组件根据当前路线检索并显示餐厅信息。
更新主应用程序组件。
导航到 client/src/app/app.ts文件并将内容替换为以下代码:
import { Component } from '@angular/core'; import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router'; ({ 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文件并将内容替换为以下代码:
<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>
这是主要的应用程序组件,其中包括导航并根据当前路由呈现相应的子组件。
更新主文件。
导航到 client/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));
此文件充当应用程序的入口点,并应用和呈现您的配置。
运行应用程序
最后,按照本节中的步骤运行应用程序并查看呈现的餐厅数据。
运行客户端应用程序。
在另一个终端窗口中,导航到 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请求以检索数据。
打开应用程序站点。
打开 http://localhost:4200 / URL。初始登陆页面显示sample_restaurants.restaurants 集合中所有餐厅的列表:

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

恭喜您完成快速入门教程!
完成这些步骤后,您就拥有了一个Angular Web应用程序,它可以连接到您的MongoDB 部署、对示例餐厅数据运行查询,并在本地托管的网站上呈现结果。
其他资源
要学习;了解有关Angular、 MongoDB和MEAN堆栈的更多信息,请查看以下资源: