You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node+Express+Mongo+Pug MVC应用:如何聚合多模块数据到首页?

问题描述

我有一个基于Node+Express+Mongo+Pug的MVC应用,目前已实现stories、questions、reviews等独立模块(每个模块包含Controller+Model+View,可完成MongoDB数据写入与视图展示)。现在需要创建新控制器,将这些模块的数据聚合后在首页按行展示,对该控制器的实现方式存在困惑。

以下是单个Story模块的示例代码:

Story模块示例

控制器代码

const Story = require('../models/Story');

exports.getStories = (req, res, next) => {
  Story.find()
  .then((stories) => {
    res.render('story', {title:'StoryTata', stories});
  })
  .catch(() => { res.send('Sorry!'); });
};

视图代码(Pug)

extends layout

block content
    body
        h1 #{title}
        if stories
            table
              tr
                th Title
                th Body
                th userName
              each story in stories
                tr
                  td= story.title
                  td= story.body
                  td= story.userName
        else
            p No registrations yet :(
            
        a(href='/story/add') Add New Story

模型代码

// storyModel
let mongoose = require('mongoose');

// Add Story
let storySchema = mongoose.Schema({
    title:{
        type:String,
        required: true
    },
    body:{
        type:String,
        required: true
    },
    userName:{
        type: String,
        required: true
    } 
}, { timestamps: true });

let Story = module.exports = mongoose.model('Story', storySchema);

解决方案

1. 创建首页控制器

核心思路是并行查询多个模块的数据,通过Promise.all同时发起MongoDB查询,待所有数据返回后统一传递给首页视图。

控制器代码(controllers/home.js)

const Story = require('../models/Story');
const Question = require('../models/Question');
const Review = require('../models/Review');

// 首页数据聚合控制器
exports.getHome = (req, res, next) => {
  // 并行执行三个模块的数据查询
  Promise.all([
    // 可选:按创建时间倒序,取最新5条数据(避免首页加载过多内容)
    Story.find().sort({ createdAt: -1 }).limit(5),
    Question.find().sort({ createdAt: -1 }).limit(5),
    Review.find().sort({ createdAt: -1 }).limit(5)
  ])
  .then(([stories, questions, reviews]) => {
    // 将所有模块数据传递给首页视图
    res.render('home', {
      title: '首页',
      stories,
      questions,
      reviews
    });
  })
  .catch(err => {
    console.error('首页数据加载失败:', err);
    res.send('加载数据失败,请稍后重试');
  });
};

2. 编写首页Pug视图

在视图中按模块拆分展示数据,每个模块对应一个区块,按行展示内容:

视图代码(views/home.pug)

extends layout

block content
  h1 首页

  // 故事模块展示区
  section
    h2 最新故事
    if stories.length
      table
        tr
          th 标题
          th 内容预览
          th 作者
        each story in stories
          tr
            td= story.title
            td= story.body.substring(0, 60) + '...' // 截断长内容,优化展示
            td= story.userName
    else
      p 暂无故事内容

  // 问题模块展示区
  section
    h2 最新问题
    if questions.length
      table
        tr
          th 标题
          th 内容预览
          th 提问者
        each question in questions
          tr
            td= question.title
            td= question.content.substring(0, 60) + '...'
            td= question.userName
    else
      p 暂无问题内容

  // 评价模块展示区
  section
    h2 最新评价
    if reviews.length
      table
        tr
          th 标题
          th 评价预览
          th 评价者
        each review in reviews
          tr
            td= review.title
            td= review.content.substring(0, 60) + '...'
            td= review.userName
    else
      p 暂无评价内容

3. 配置首页路由

在路由文件(如routes/index.js或app.js)中添加首页路由:

const homeController = require('../controllers/home');

// 首页路由
app.get('/', homeController.getHome);

关键说明

  • 并行查询优化:使用Promise.all替代嵌套回调,同时发起多个MongoDB查询,大幅提升数据加载效率。
  • 数据筛选:通过sort({ createdAt: -1 })按创建时间倒序,limit(5)限制返回数量,避免首页加载过多数据影响性能。
  • 错误处理:统一捕获所有查询的错误,打印日志并返回友好提示,便于排查问题。

内容的提问来源于stack exchange,提问作者aksit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:40:28