在Express中多次SELECT查询后呈现视图

bar*_*gro 8 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 */});
});
Run Code Online (Sandbox Code Playgroud)

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

我知道匿名函数导致了一个问题.我已经尝试将问题解决了五个多小时,如下所示:

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

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

请注意,连接表是不可能的 - 事实上,我想制作4-5个查询,然后渲染我的视图.我正在使用SQLite3数据库.

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

The*_*per 15

在你的情况下,我会将数据库调用分成单独的调用,并使用 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);
Run Code Online (Sandbox Code Playgroud)

当你GET时/student,你先打电话findStudent.db调用完成后,它将呈现错误页面,或调用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();
    });
}
Run Code Online (Sandbox Code Playgroud)

然后在代码的其他地方,您可以处理渲染错误页面.