Node.js - 将多个对象传递给同一个 EJS 文件

Posted

技术标签:

【中文标题】Node.js - 将多个对象传递给同一个 EJS 文件【英文标题】:Node.js - Passing multiple objects to same EJS file 【发布时间】:2017-05-11 04:44:05 【问题描述】:

我有多个 mysql 查询结果,其中我呈现第一个并将其余的可调用到单个 EJS 文件 (/data) 作为对象。

我只呈现 first 查询结果 (obj),然后将其余的可调用到 EJS (rsum_total_sales & rsum_count_active)

似乎我第一次加载 EJS 文件时遇到前端 500 错误,例如

   rsum_total_sales is not defined

但是当我重新加载浏览器时,我可以让 EJS 正常加载,显示从路由文件中获得的所有需要​​的结果。

奇怪的是,即使是第一次,在 console.log() 中,我看到所有三个查询结果都已放入我创建的对象中,但是除了第一个直接呈现到的对象之外,它们还不能被 EJS 调用它。

从 EJS 错误中,我可以看到它传递了第一个 connection.query 结果 (obj),它被渲染,但没有传递其余两个 (rsum_total_sales 和 sum_count_active),我只是让它们的对象可调用,直到我重新加载浏览器。

路由文件

var obj = ;
var qsum_total_sales = 'SELECT SUM (total_price) AS s_total_price FROM myrecords'; 
var qsum_count_active = 'SELECT COUNT (*) AS s_count_active FROM myrecords WHERE NOT status = "canceled" ';
var qdata = 'SELECT * FROM myrecords';

router.get('/data', function(req, res)
    connection.query(qdata, function(err, result) 
        if(err)
            throw err;
            else 
                obj = print: result;
                res.render('data', obj);
                console.log(obj);
        
    );

   connection.query(qsum_total_sales, function(err, rows, result) 
       if(err)
           throw err;
        else 
           rsum_total_sales = JSON.parse(rows[0].s_total_price).toFixed(2);
           console.log(rsum_total_sales); 
           //First time prints result but it can't be called to EJS until reloading EJS
       
   );

  connection.query(qsum_count_active, function(err, rows, result) 
       if(err)
           throw err;
        else 
           rsum_count_active = JSON.parse(rows[0].s_count_active);
           console.log(rsum_count_active);  
           //First time prints result but it can't be called to EJS until reloading EJS
       
   ); 
);

EJS 文件

<tbody>
    <% print.forEach(function (datatable)  %>
        <tr>
             <td><%= datatable.id %></td
             <td><%= datatable.full_name %></td>
             //rest of loop
         </tr>                              
        <% ) %>
</tbody>
    // some html code
<h4>Total sales sum is: <%- rsum_total_sales %></h4>
<h4>Total active records are: <%- rsum_count_active %></h4>

前端错误(仅当 EJS 第一次加载到浏览器时)

ReferenceError: C:\NodeJS\CRUD-1\views\data.ejs:39
    37|         </table>
    38|         <hr/>
>>  39|         <h4>Total sales sum is: <%- rsum_total_sales %></h4>
    40|         <h4>Total active records are: <%- rsum_count_active %></h4>

rsum_total_sales is not defined
at eval (eval at <anonymous> (C:\NodeJS\CRUD-1\node_modules\ejs\lib\ejs.js:481:12),
<anonymous>:47:17)
at returnedFn (C:\NodeJS\CRUD-1\node_modules\ejs\lib\ejs.js:512:17)
at View.exports.renderFile [as engine] (C:\NodeJS\CRUD- 1\node_modules\ejs\lib\ejs.js:364:31)
at View.render (C:\NodeJS\CRUD-1\node_modules\express\lib\view.js:126:8)
at tryRender (C:\NodeJS\CRUD-1\node_modules\express\lib\application.js:639:10)
at EventEmitter.render (C:\NodeJS\CRUD-1\node_modules\express\lib\application.js:591:3)
at ServerResponse.render (C:\NodeJS\CRUD-1\node_modules\express\lib\response.js:960:7)
at Query._callback (C:\NodeJS\CRUD-1\routes\data.js:36:17)
at Query.Sequence.end (C:\NodeJS\CRUD-1\node_modules\mysql\lib\protocol\sequences\Sequence.js:86:24)
at Query._handleFinalResultPacket (C:\NodeJS\CRUD-1\node_modules\mysql\lib\protocol\sequences\Query.js:144:8)

【问题讨论】:

我看不到你在哪里发送 rsum_total_salesrsum_count_active 到前端。 【参考方案1】:

我看不到你将rsum_total_salesrsum_count_active 发送到前端。此外,您正在分别运行 3 个 queriessecond 一个不会等待 first 一个完成,同样third 一个不会等待第二个完成。

一旦第一个完成,它会将数据(obj)发送回client(front-end),并且不会等待secondthird query 完成,因此您不知道您是否得到了front-end中的所有data

你应该在第一个回调中做第二个,在第二个回调中做第三个,并在第三个查询成功完成后将obj发送到前端。这样可以确保所有的数据都到前端。

试试这个:

var obj = ;
var qsum_total_sales = 'SELECT SUM (total_price) AS s_total_price FROM myrecords';
var qsum_count_active = 'SELECT COUNT (*) AS s_count_active FROM myrecords WHERE NOT status = "canceled" ';
var qdata = 'SELECT * FROM myrecords';

router.get('/data', function(req, res) 
  connection.query(qdata, function(err, result) 
    if (err) 
      throw err;
     else 
      obj = 
        print: result
      ;

      console.log(obj);
      connection.query(qsum_total_sales, function(err, rows, result1) 
        if (err) 
          throw err;
         else 
          rsum_total_sales = JSON.parse(rows[0].s_total_price).toFixed(2);
          console.log(rsum_total_sales);


          connection.query(qsum_count_active, function(err, rows2, result2) 
            if (err) 
              throw err;
             else 
              rsum_count_active = JSON.parse(rows2[0].s_count_active);
              console.log(rsum_count_active);

              //After successful completion of all 3 queries send data back to cliend(front-end)
              //its better to create new obj everytime and send it
              //store all the data in obj and send back to client
              var obj = ;
              obj.print = result;
              obj.rsum_count_active = rsum_count_active;
              obj.rsum_total_sales = rsum_total_sales;
              res.render('data', obj);
            
          );
        
      );
    
  );

);

【讨论】:

这是非常清晰和合乎逻辑的解释并且确实有效。如果它是一个插图概念,它显然让我大开眼界。然而,它显示了所谓的“回调地狱”或“厄运之山”的最初症状。想象一下,在某些时候可能需要有 5 或 10 个不同的查询,它们的结果将被呈现到同一个 EJS 文件中。 在这种情况下,您可以使用promises 而不是callbacks,您将不必处理callback hell 的问题。 我接受您的回答,因为它以自己的方式(使用callbacks 而不是 promises)帮助解决了我的问题,至少目前在哪里我只有几个问题。我肯定会在接下来的几天内尝试将其转换为 promises 方法。 我会更新我的答案,向您展示如何使用promises 执行此操作,但我认为我引导您朝着正确的方向解决您的问题。现在,轮到你努力工作并用承诺来实现它了,如果你在实现它时遇到任何问题,你可以随时通过这个评论联系我,我很乐意再次帮助你。

以上是关于Node.js - 将多个对象传递给同一个 EJS 文件的主要内容,如果未能解决你的问题,请参考以下文章

在 node/express + ejs 中将对象传递给客户端?

将参数传递给回调 node.js

如何将命令行参数传递给 Node.js 程序?

如何将命令行参数传递给 Node.js 程序?

如何将命令行参数传递给 Node.js 程序?

如何将命令行参数传递给 Node.js 程序?