基于NodeJS实现AngularJS应用与MongoDB的连接及数据同步
好的,咱们一步步把你的AngularJS书籍管理应用和MongoDB打通,实现数据的实时同步增删改查。我会分成后端Node.js服务搭建和前端AngularJS代码修改两部分来讲解,确保每一步都清晰易懂。
第一步:搭建Node.js后端(连接MongoDB)
首先得搞个后端服务,负责和MongoDB交互,给前端提供API接口。
1. 初始化项目&安装依赖
先创建一个新文件夹(比如book-server),进入文件夹后执行命令:
npm init -y npm install express mongoose cors body-parser
这些依赖的作用:
express:快速搭建Web服务mongoose:MongoDB的ODM工具,简化数据库操作cors:解决前后端跨域问题body-parser:解析前端发送的JSON数据
2. 编写后端代码(server.js)
创建server.js文件,写入以下代码:
const express = require('express'); const mongoose = require('mongoose'); const cors = require('cors'); const bodyParser = require('body-parser'); const app = express(); const PORT = 3000; // 连接MongoDB(本地地址替换成你的实际MongoDB地址) mongoose.connect('mongodb://localhost:27017/bookDB', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('MongoDB连接成功!')) .catch(err => console.error('MongoDB连接失败:', err)); // 定义书籍Schema和Model,对应你前端的数据结构 const bookSchema = new mongoose.Schema({ name: String, lName: String, // 作者名 passw1: String, // 出版日期 pages: String }); const Book = mongoose.model('Book', bookSchema); // 中间件配置 app.use(cors()); app.use(bodyParser.json()); // API路由:获取所有书籍 app.get('/api/books', async (req, res) => { try { const books = await Book.find(); // 转换格式,把MongoDB的_id映射成前端用的id const formattedBooks = books.map(book => ({ id: book._id, name: book.name, lName: book.lName, passw1: book.passw1, pages: book.pages })); res.json(formattedBooks); } catch (err) { res.status(500).json({ error: '获取数据失败' }); } }); // API路由:新增书籍 app.post('/api/books', async (req, res) => { try { const newBook = new Book(req.body); const savedBook = await newBook.save(); res.json({ id: savedBook._id, ...savedBook._doc }); } catch (err) { res.status(500).json({ error: '新增书籍失败' }); } }); // API路由:更新书籍 app.put('/api/books/:id', async (req, res) => { try { const updatedBook = await Book.findByIdAndUpdate( req.params.id, req.body, { new: true } // 返回更新后的文档 ); if (!updatedBook) { return res.status(404).json({ error: '书籍不存在' }); } res.json({ id: updatedBook._id, ...updatedBook._doc }); } catch (err) { res.status(500).json({ error: '更新书籍失败' }); } }); // API路由:删除书籍 app.delete('/api/books/:id', async (req, res) => { try { const deletedBook = await Book.findByIdAndDelete(req.params.id); if (!deletedBook) { return res.status(404).json({ error: '书籍不存在' }); } res.json({ message: '删除成功' }); } catch (err) { res.status(500).json({ error: '删除书籍失败' }); } }); // 启动服务 app.listen(PORT, () => { console.log(`后端服务运行在 http://localhost:${PORT}`); });
第二步:修改AngularJS前端代码
现在把前端的本地数据换成从后端获取,同时修改增删改逻辑,让它们调用后端API。
1. 修改模块依赖
移除ngMockE2E(不需要模拟数据了),更新模块定义:
var app = angular.module("app", ["xeditable"]);
2. 更新控制器核心逻辑
给控制器注入$http服务,替换本地数组为后端请求,同时修改增删改方法:
app.controller('Ctrl', function($scope, $filter, filteredListService, $http) { // 页面初始化:从后端拉取数据 $scope.init = function() { $http.get('/api/books') .then(function(response) { $scope.users = response.data; $scope.allItems = $scope.users; $scope.resetAll(); $scope.pagination(); }) .catch(function(err) { console.error('获取数据失败:', err); }); }; // 保留原有名称校验逻辑 $scope.checkName = function(data, id) { if (id === 2 && data !== 'narnia') { return "Username 2 should be `narnia(case sensitive)`"; } }; // 保存更新:调用后端PUT接口 $scope.saveUser = function(data, id) { return $http.put(`/api/books/${id}`, data) .then(function(response) { // 更新本地数据 const index = $scope.users.findIndex(user => user.id === id); if (index !== -1) { $scope.users[index] = response.data; $scope.allItems = $scope.users; $scope.resetAll(); } }) .catch(function(err) { console.error('更新失败:', err); return err.data.error; // 返回错误信息给前端提示 }); }; // 删除书籍:调用后端DELETE接口 $scope.removeUser = function(index) { const actualIndex = index + $scope.currentPage * $scope.pageSize; const bookId = $scope.users[actualIndex].id; $http.delete(`/api/books/${bookId}`) .then(function() { $scope.users.splice(actualIndex, 1); $scope.allItems = $scope.users; $scope.pagination(); }) .catch(function(err) { console.error('删除失败:', err); }); }; // 新增书籍:调用后端POST接口 $scope.addUser = function($event) { const newBook = { name: 'Enter Book Name', lName: 'Author Name', passw1: 'Date of Publish', pages: 'Pages' }; $http.post('/api/books', newBook) .then(function(response) { $scope.users.push(response.data); $scope.allItems = $scope.users; $scope.currentPage = Math.floor(($scope.users.length - 1) / $scope.pageSize); $scope.pagination(); $scope.resetAll(); }) .catch(function(err) { console.error('新增失败:', err); }); }; // 原有搜索、分页逻辑保留,无需修改 $scope.pageSize = 4; $scope.reverse = false; $scope.resetAll = function() { $scope.filteredList = $scope.allItems; $scope.newEmpId = ''; $scope.newName = ''; $scope.newEmail = ''; $scope.searchText = ''; $scope.currentPage = 0; $scope.Header = ['', '', '']; }; $scope.pagination = function() { $scope.ItemsByPage = filteredListService.paged($scope.filteredList, $scope.pageSize); }; $scope.setPage = function() { $scope.currentPage = this.n; }; $scope.firstPage = function() { $scope.currentPage = 0; }; $scope.lastPage = function() { $scope.currentPage = $scope.ItemsByPage.length - 1; }; $scope.range = function(input, total) { var ret = []; if (!total) { total = input; input = 0; } for (var i = input; i < total; i++) { if (i != 0 && i != total - 1) { ret.push(i); } } return ret; }; $scope.sort = function(sortBy) { $scope.resetAll(); $scope.pagination(); }; $scope.search = function() { $scope.filteredList = filteredListService.searched($scope.allItems, $scope.searchText); if ($scope.searchText == '') { $scope.filteredList = $scope.allItems; } $scope.pagination(); }; // 页面加载时执行初始化 $scope.init(); });
3. 其他小调整
- 移除HTML中不必要的
angular-mocks.js引用(如果不需要测试) - 确保页面结构和原有
ng-repeat、编辑组件逻辑保持不变
第三步:运行测试
- 启动MongoDB服务(确保你的MongoDB已安装并正常运行)
- 启动后端:在
book-server文件夹执行node server.js - 启动前端:可以用
http-server(先安装npm install -g http-server),在前端文件夹执行http-server后访问对应地址(比如http://localhost:8080)
现在你操作页面上的增删改查,所有变更都会实时同步到MongoDB里啦!
内容的提问来源于stack exchange,提问作者sahil
相关产品推荐
相关产品推荐

