【问题标题】:Pass Data Value from MongoDB to ejs Template in Node.js将数据值从 MongoDB 传递到 Node.js 中的 ejs 模板
【发布时间】:2018-08-18 15:37:14
【问题描述】:

我有一个快速应用程序,我在其中使用 ejs 来呈现视图。例如,这是我的观点之一:

<a href="/admin/categories" class="list-group-item">
                            <span style="margin-right: 6px" class="glyphicon glyphicon-folder-close"></span>
                            Categories
                            <span class="badge categoriesCount"><%= catCount %></span> <!-- get data from mongo -->
                        </a>

在我的路由文件中,我从 mongodb 获取了值并尝试将它们传递到视图中,例如:

router.get('/', (req, res) => {

let cat_count = 0,
    prod_count = 0,
    user_count = 0,
    order_count = 0;

Category.count({}, (err, count) => {
    if (!err) {
        cat_count = count;
        console.log('Cat count from db:\t' + count);
    } else {
        console.error('Error Fetching Categories Count:\t' + err);
    }
});

Products.count({}, (err, count) => {
    if (!err) {
        prod_count = count;
        console.log('Prod count from db:\t' + count);
    } else {
        console.error('Error Fetching Products Count:\t' + err);
    }
});

Users.count({}, (err, count) => {
    if (!err) {
        user_count = count;
        console.log('User count from db:\t' + count);
    } else {
        console.error('Error Fetching Users Count:\t' + err);
    }
});

Orders.count({}, (err, count) => {
    if (!err) {
        order_count = count;
        console.log('Orders count from db:\t' + count);
    } else {
        console.error('Error Fetching Orders Count:\t' + err);
    }
});

res.render('index', {
    catCount: cat_count,
    prodCount: prod_count,
    userCount: user_count,
    orderCount: order_count
  });
});

catCount 是模板中变量的实际参数。这不起作用,我一直在想办法解决这个问题。

我也尝试过使用DOM querySelector('className').innerHTML,但这也不起作用。

向我的模板发送值的最佳方式是,我更喜欢 ejs。 谢谢。

【问题讨论】:

  • 我认为你正在做的应该工作。你有什么错误吗?
  • @HarshalGangurde 没有错误
  • 在我的模板中,当我悬停变量时,它显示未解析的变量或类型 catCount。知道这意味着什么吗?

标签: javascript node.js express ejs


【解决方案1】:

您的代码将不起作用,因为您的计数变量的值只会在回调运行后被分配。在处理回调时,您必须注意,当您运行主函数时,回调函数中的代码不会立即执行。您现在拥有的内容类似于以下内容:

// initialize variables
// execute Category.count({}) and call the function that you passed in when data is ready
// execute Products.count({}) and call the function that you passed in when data is ready
// execute Users.count({}) and call the function that you passed in when data is ready
// execute Orders.count({}) and call the function that you passed in when data is ready
// render

所有这 5 行代码将在瞬间运行,并且在调用这些回调函数之前不会等待。解决它的一种方法是将所有回调嵌套在一起:

router.get('/', (req, res) => {

  let cat_count = 0,
      prod_count = 0,
      user_count = 0,
      order_count = 0;

  Category.count({}, (err, count) => {
    if (!err) {
      cat_count = count;
      console.log('Cat count from db:\t' + count);

      Products.count({}, (err, count) => {
        if (!err) {
          prod_count = count;
          console.log('Prod count from db:\t' + count);

          Users.count({}, (err, count) => {
            if (!err) {
              user_count = count;
              console.log('User count from db:\t' + count);

              Orders.count({}, (err, count) => {
                if (!err) {
                  order_count = count;
                  console.log('Orders count from db:\t' + count);

                  res.render('index', {
                    catCount: cat_count,
                    prodCount: prod_count,
                    userCount: user_count,
                    orderCount: order_count
                  });
                } else {
                  console.error('Error Fetching Orders Count:\t' + err);
                }
              });
            } else {
              console.error('Error Fetching Users Count:\t' + err);
            }
          });
        } else {
          console.error('Error Fetching Products Count:\t' + err);
        }
      });
    } else {
      console.error('Error Fetching Categories Count:\t' + err);
    }
  });
});

然而,这真的很混乱,在 JavaScript 中被称为 回调地狱。这就是Promises 派上用场的地方。

您可以这样做:

router.get('/', (req, res) => {
  let queries = [
    Category.count({}), 
    Products.count({}), 
    Users.count({}), 
    Orders.count({})
  ];

  Promise.all(queries)
  .then(results => {
    res.render('index', {
      catCount: results[0],
      prodCount: results[1],
      userCount: results[2],
      orderCount: results[3]
    });
  })
  .catch(err => {
    console.error('Error fetching data:', err)
  });
});

对于 Mongoose,当你不传入一个函数作为第二个参数时,函数调用返回的值(例如Category.count({}))将是一个 Promise。我们会将所有这些未解决的 Promise 放入一个数组中并调用Promise.all 来解决它们。通过使用Promise.all,您将等待所有计数查询都执行完毕,然后再继续呈现您的index 视图。在这种情况下,您的 Mongoose 函数调用的结果将按照您的 queries 数组的顺序存储在 results 数组中。

【讨论】:

  • 你真是太棒了,谢谢你的解释,主要是承诺部分。祝你有美好的一天!
猜你喜欢
  • 2018-12-02
  • 2018-05-14
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-14
  • 1970-01-01
相关资源
最近更新 更多