在Express中执行多个SELECT查询后渲染视图 [英] Rendering view after multiple SELECT queries in Express

查看:263
本文介绍了在Express中执行多个SELECT查询后渲染视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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){
/ *保存数据* /
}
else
res.render('incorrect_student'); / *渲染错误页面* /
});

dbRequest ='SELECT * FROM Groups WHERE Name = \''+ req.query ['group'] +'\'';
db.all(dbRequest,function(error,rows){
/ *将所选数据添加到以前保存数据* /
}
});
res.render('student',{data:/ *来自上述两个查询的数据* /});
}) ;

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



我知道匿名功能引起的问题。我已经尝试解决这个问题超过五个小时,如下所示:


  1. 将匿名的对象克隆到另一个匿名者功能,然后传递给 res.render 。该解决方案不能工作,因为复制对象的值在该函数之外不可见(未定义) - 仅在其中。

  2. 学生页面呈现两次 - 这真的是天真的。

  3. db.all 命令更改为 db.prepare ,然后将 db.run - 它不工作。

  4. 通过匿名函数返回对象,然后将其分配给在 app.get 之间定义的外部对象> var dbRequest 。结果如第一点所述。

我也有一个想法,创建子页面学生页面,它只需要一个查询的变量。另一个想法是使用 db req res 应用对象的其他功能。但是,正如我之前所说的,我是Express的新人,我不知道如何实现我的上述想法。



请注意,不可能加入表 - 其实我想做4-5个查询,然后渲染我的观点。我正在使用SQLite3数据库。



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

解决方案

在你的情况下,我将数据库调用分解成单独的电话,并使用下一个中间件功能。



它看起来像:

  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'); / *渲染错误页面* /
});
}

函数findGroups(req,res,next){
dbRequest ='SELECT * FROM Groups WHERE Name = \''+ req.query ['group'] +'\'';
db.all(dbRequest,function(error,rows){
/ *将所选数据添加到以前保存的数据* /
req.groups = rows;
next() ;
}
});
}

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

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

当您获得 / student 调用 findStudent 。一旦数据库调用完成,它将会呈现一个错误页面,或者调用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();
});
}

然后你代码中的其他地方可以处理渲染错误页面。 >

I'm a bit new in Node.JS and Express framework and I have a great problem with the code below:

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 */});
});

As I have written in comment blocks, I would like to: execute first select query, save data from rows object, execute second query, again save received data in other object and then finally render the page passing data from both queries. My question is, what is the best way to do that?

I know that there is a problem caused by anonymous function. I have tried to fix the problem for over five hours as follows:

  1. Clone rows object to another in anonymous function and then pass it to res.render. This solution dosen't work, because values of copied object are not visible (undefined) outside this function - only inside it.
  2. Render the student page twice - it was really naive of course.
  3. Change db.all command to db.prepare and then db.run - it wasn't working too.
  4. Return object by the anonymous function and then assign it to external object defined between app.get and var dbRequest. The result was as described in 1st point.

I have also an idea to create "subpages" containig parts of student page, which need variables from only one query. The other idea is to use some other functions of db, req, res or app objects. But, as I said before, I'm new in Express and I don't know how to realize my above ideas.

Please note that it is impossible to join tables - in fact, I want to make 4-5 queries and then render my view. I'm using SQLite3 database.

Thank you very much for your help! I hope that you'll help me to solve my problem.

解决方案

In your situation, I would split up the database calls into separate calls, and make use of the next middleware function.

It would looks something like:

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);

When you GET /student, you first call findStudent. Once the db call is finished, it will either render an error page, or call next(). Calling next goes to the next function, findGroups, which will then call renderStudentsPage. You can store the data on the req object as you move down the line of functions.

Hope this helps, and here is more info: http://expressjs.com/guide/using-middleware.html


edit/note:

I did not mention it earlier, but if you pass in an argument when calling next(), you will trigger the error handling state. Convention dictates next() is left parameter-less unless you have met an error instance.

You want to separate out the UI rendering aspect from the database call, so going further, your code could look like:

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();
    });
}

And then elsewhere in your code you can handle rendering error pages.

这篇关于在Express中执行多个SELECT查询后渲染视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆