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

Express+EJS项目中如何在路由调用控制器函数并传数据至视图?

解决Express+EJS项目中控制器数据无法传递到视图的问题

我来帮你分析下问题所在,然后一步步解决:

核心问题分析

你的代码里有两个关键问题导致视图拿不到数据:

  1. 异步操作处理错误:banners函数里的数据库查询是异步操作,你直接在回调里return results根本无法把数据传递出去——异步回调的return不会让外部函数返回值,而且你写的var data = results在return之后,根本不会执行。
  2. 路由调用方式错误:你在路由里把home.banners这个函数对象直接传给了视图,而没有执行它去获取数据库数据,视图拿到的只是一个函数,不是实际的查询结果。

解决方案步骤

第一步:修改控制器home.js,正确处理异步数据传递

我们把banners改成支持回调(或者Promise,推荐后者)的方式,让它能把异步查询到的数据传递出去:

方式1:使用回调函数

var config = require('../../config/config');
// 假设connection是你已经配置好的数据库连接实例
exports.banners = function(callback) {
  // 连接数据库
  connection.connect(function(err) {
    if (err) {
      console.error('数据库连接失败:', err);
      return callback(err, null); // 把错误传给回调
    }
    console.log('数据库连接成功...');
    
    // 执行查询
    connection.query(
      'SELECT * FROM banner_management WHERE banner_status ="Active" AND banner_type = "home_page" Limit 0,1',
      function(err, results) {
        // 查询完成后关闭连接(如果是单次连接的话,用连接池可以省略这步)
        connection.end();
        
        if (err) {
          console.error('Banner查询失败:', err);
          return callback(err, null);
        }
        // 把查询结果通过回调返回
        callback(null, results);
      }
    );
  });
}

方式2:使用Promise(更现代,推荐)

var config = require('../../config/config');
exports.banners = function() {
  return new Promise((resolve, reject) => {
    connection.connect(function(err) {
      if (err) {
        console.error('数据库连接失败:', err);
        return reject(err);
      }
      console.log('数据库连接成功...');
      
      connection.query(
        'SELECT * FROM banner_management WHERE banner_status ="Active" AND banner_type = "home_page" Limit 0,1',
        function(err, results) {
          connection.end();
          if (err) {
            console.error('Banner查询失败:', err);
            return reject(err);
          }
          resolve(results);
        }
      );
    });
  });
}

第二步:修改路由文件,正确调用控制器并渲染视图

根据你选择的控制器方式,修改路由代码:

如果用回调方式

// 把require放在路由文件顶部,不要在请求处理函数里重复加载
var home = require('../app/controllers/home');

/* GET home page. */
router.get('/', function(req, res, next) {
  // 调用banners函数,传入回调处理结果
  home.banners(function(err, bannerData) {
    if (err) {
      // 把错误交给Express的错误处理中间件
      return next(err);
    }
    // 拿到数据后再渲染视图
    res.render('index', { 
      title: 'Medical Tourism-Arogyata',
      data: bannerData, 
      baseUrl: 'http://localhost:3000/' 
    });
  });
});

如果用Promise方式(推荐用async/await简化代码)

var home = require('../app/controllers/home');

/* GET home page. */
router.get('/', async function(req, res, next) {
  try {
    // 等待异步查询完成拿到数据
    const bannerData = await home.banners();
    // 渲染视图并传递数据
    res.render('index', { 
      title: 'Medical Tourism-Arogyata',
      data: bannerData, 
      baseUrl: 'http://localhost:3000/' 
    });
  } catch (err) {
    // 捕获错误并交给错误中间件
    next(err);
  }
});

额外优化建议

  • 数据库连接池:每次请求都创建新的数据库连接效率很低,建议改用连接池(比如mysql的createPool方法),在config里配置好连接池,然后每次从池里获取连接,避免频繁创建/关闭连接。
  • 错误处理:在生产环境中不要直接throw err,最好把错误传递给Express的错误处理中间件统一处理。

内容的提问来源于stack exchange,提问作者Surya prakash Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:04:35