我对 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 中所写的那样,我想:执行第一个选择查询,从行对象保存数据,执行第二个查询,再次将接收到的数据保存在其他对象中,然后最后呈现页面传递来自两个查询的数据。我的问题是,最好的方法是什么?
我知道是匿名函数引起的问题。我已尝试按以下方式解决问题超过五个小时:
- 将 rows 对象克隆到匿名函数中的另一个对象,然后将其传递给 res.render。此解决方案不起作用,因为复制对象的值在此函数外不可见(未定义) - 仅在函数内可见。
- 渲染 student 页面两次 - 当然这真的很天真。
- 将 db.all 命令更改为 db.prepare,然后是 db.run - 它也不起作用。
- 通过匿名函数返回对象,然后将其分配给定义在app.get 和var dbRequest 之间的外部对象。结果如第 1 点所述。
我还有一个想法是创建包含学生 页面部分的“子页面”,它只需要来自一个查询的变量。另一个想法是使用 db、req、res 或 app 对象的一些其他功能。但是,正如我之前所说,我是 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/