node.js - 在 Express 中多次 SELECT 查询后呈现 View

标签 node.js express

我对 Node.JS 和 Express 框架有点陌生,我对下面的代码有很大的疑问:

app.get('/student', function(req, res) {
    var dbRequest = 'SELECT * FROM Students WHERE IDCard = \'' + req.query['id'] + '\'';
    db.all(dbRequest, function(error, rows) {
        if(rows.length !== 0) {
            /* Save data. */
        }   
        else
            res.render('incorrect_student'); /* Render the error page. */
    });

    dbRequest = 'SELECT * FROM Groups WHERE Name = \'' + req.query['group'] + '\'';
        db.all(dbRequest, function(error, rows) {
            /* Add selected data to previous saved data. */
        }
    });
    res.render('student', {data: /* data from both queries above */});
});

正如我在评论 block 中所写的那样,我想:执行第一个选择查询,从对象保存数据,执行第二个查询,再次将接收到的数据保存在其他对象中,然后最后呈现页面传递来自两个查询的数据。我的问题是,最好的方法是什么?

我知道是匿名函数引起的问题。我已尝试按以下方式解决问题超过五个小时:

  1. rows 对象克隆到匿名函数中的另一个对象,然后将其传递给 res.render。此解决方案不起作用,因为复制对象的值在此函数外不可见(未定义) - 仅在函数内可见。
  2. 渲染 student 页面两次 - 当然这真的很天真。
  3. db.all 命令更改为 db.prepare,然后是 db.run - 它也不起作用。
  4. 通过匿名函数返回对象,然后将其分配给定义在app.getvar dbRequest 之间的外部对象。结果如第 1 点所述。

我还有一个想法是创建包含学生 页面部分的“子页面”,它只需要来自一个查询的变量。另一个想法是使用 dbreqresapp 对象的一些其他功能。但是,正如我之前所说,我是 Express 的新手,我不知道如何实现我的上述想法。

请注意,连接表是不可能的——事实上,我想进行 4-5 次查询,然后呈现我的 View 。我正在使用 SQLite3 数据库。

非常感谢您的帮助!我希望你能帮助我解决我的问题。

最佳答案

在您的情况下,我会将数据库调用拆分为单独的调用,并使用 next 中间件函数。

它看起来像:

function findStudent(req, res, next) {
    var dbRequest = 'SELECT * FROM Students WHERE IDCard = \'' + req.query['id'] + '\'';
    db.all(dbRequest, function(error, rows) {
        if(rows.length !== 0) {
            req.students = rows;
            return next();
        }

        res.render('incorrect_student'); /* Render the error page. */            
    });
}

function findGroups(req, res, next) {
    dbRequest = 'SELECT * FROM Groups WHERE Name = \'' + req.query['group'] + '\'';
        db.all(dbRequest, function(error, rows) {
            /* Add selected data to previous saved data. */
            req.groups = rows;
            next();
        }
    });
}

function renderStudentsPage(req, res) {
    res.render('student', {
        students: req.students,
        groups: req.groups
    });
}

app.get('/student', findStudent, findGroups,  renderStudentsPage);

当你获取/student时,你首先调用findStudent。一旦 db 调用完成,它将呈现一个错误页面,或者调用 next()。调用 next 转到下一个函数 findGroups,然后调用 renderStudentsPage。您可以在向下移动函数行时将数据存储在 req 对象上。

希望这对您有所帮助,这里有更多信息: http://expressjs.com/guide/using-middleware.html


编辑/注释:

我之前没有提到,但是如果你在调用next()时传入一个参数,就会触发错误处理状态。约定要求 next() 没有参数,除非遇到错误实例。

您想将 UI 渲染方面与数据库调用分开,因此更进一步,您的代码可能如下所示:

function findStudent(req, res, next) {
    var dbRequest = 'SELECT * FROM Students WHERE IDCard = \'' + req.query['id'] + '\'';
    db.all(dbRequest, function(error, rows) {

        if (error || !rows.length) {
            return next(error);
        }

        req.students = rows;
        return next();
    });
}

然后您可以在代码的其他地方处理呈现错误页面。

关于node.js - 在 Express 中多次 SELECT 查询后呈现 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28128323/

相关文章:

javascript - node.js mySQL 获取记录

node.js - 如何使用 mongoose update 并更新嵌入文档?

javascript - 如何使用 Express 中的函数呈现 Jade 模板中的内容?

node.js - SailsJS v0.10 多关联查找模型

express - 如何创建与现有对象关联的元素

当向没有响应的服务器发出 http.request 时出现 node.js 错误

node.js - Spring Security 替代 Node.js

node.js - 无法从 aws-lambda 解析 "nodejs/"目录下的自定义依赖项

javascript - 等待在 nodejs 中正确连接到 rabbit

javascript - Passport 单选按钮重定向到注册页面