Node/Express+Pug应用待审核账户通知实现及视图变量传递问题
解决方案
一、解决初始加载时Pug模板变量undefined的问题
你之前的问题根源是:Pug是服务器端渲染模板,模板中的变量是服务器在渲染页面时注入的;而Axios请求是浏览器端运行的JS代码,服务器渲染页面时还没执行这个请求,所以模板里自然拿不到变量。
正确的做法是在服务器端把初始计数传给模板,步骤如下:
- 新增全局中间件,自动注入待审核计数
在所有路由定义之前,添加一个中间件,每次请求时查询数据库并把计数存入res.locals(所有Pug模板都能直接访问这个对象里的变量):
app.use(async (req, res, next) => { try { // 替换为你的实际数据库查询逻辑,比如查找status为pending的账户数量 const pendingCount = await UserModel.countDocuments({ status: 'pending' }); res.locals.pendingCount = pendingCount; next(); } catch (err) { console.error('获取待审核账户数失败:', err); res.locals.pendingCount = 0; // 出错时默认显示0 next(); } });
- 在header.pug中直接使用变量
现在你可以在header的导航菜单里直接引用pendingCount,服务器渲染时会自动替换为实际数值:
// header.pug 示例 .nav-menu .nav-item span 待审核账户 // 通知徽章,直接使用服务器注入的变量 .notification-badge= pendingCount
二、实现账户审核后的实时更新计数
根据实时性要求,有两种简便方案:
方案1:短轮询(快速实现,适合实时性要求不高的场景)
通过前端定时请求后端接口更新计数,无需额外依赖:
- 保留你已有的
/getNumberOfPendingRegistrations接口
确保接口返回格式如下:
app.get('/getNumberOfPendingRegistrations', async (req, res) => { const numPendingUsers = await UserModel.countDocuments({ status: 'pending' }); res.json({ numPendingUsers }); });
- 在header.pug中添加前端更新脚本
// header.pug 末尾添加 script. // 更新计数的函数 function updatePendingCount() { axios.get('/getNumberOfPendingRegistrations') .then(res => { const badge = document.querySelector('.notification-badge'); if (badge) badge.textContent = res.data.numPendingUsers; }) .catch(err => console.error('更新待审核计数失败:', err)); } // 页面加载时执行一次(可选,因为服务器已经渲染了初始值) updatePendingCount(); // 每隔30秒轮询一次(可根据需求调整间隔) setInterval(updatePendingCount, 30000);
方案2:WebSocket(实时性高,适合需要即时更新的场景)
用Socket.io实现后端主动推送更新,当账户被批准/拒绝时,立刻通知所有客户端:
- 安装Socket.io依赖
npm install socket.io
- 后端配置Socket.io
修改你的服务器启动代码,集成Socket.io:
const http = require('http'); const server = http.createServer(app); const io = require('socket.io')(server); // 替换原来的app.listen为server.listen server.listen(3000, () => { console.log('服务器运行在3000端口'); });
- 在审核操作的路由中推送更新
当批准/拒绝账户后,查询最新计数并推送给所有客户端:
app.post('/approve-user', async (req, res) => { // 执行批准逻辑 await UserModel.updateOne({ _id: req.body.userId }, { status: 'approved' }); // 查询最新待审核数量 const pendingCount = await UserModel.countDocuments({ status: 'pending' }); // 向所有在线客户端推送更新 io.emit('pendingCountUpdated', pendingCount); res.json({ success: true }); }); // 拒绝账户的路由同理,操作后推送更新
- 前端监听Socket更新
在header.pug中添加Socket监听脚本:
// header.pug 末尾添加 script(src="/socket.io/socket.io.js") script. const socket = io(); // 监听后端推送的更新事件 socket.on('pendingCountUpdated', (newCount) => { const badge = document.querySelector('.notification-badge'); if (badge) badge.textContent = newCount; });
内容的提问来源于stack exchange,提问作者jocularWeasel
相关产品推荐
相关产品推荐

