我有一个快速的应用程序,我正在使用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。 感谢。
答案 0 :(得分:0)
您的代码无效,因为计数变量的值只会在回调运行后分配。处理回调时,您必须注意,当您运行main函数时,回调函数中的代码不会立即执行。你现在拥有的是以下内容:
// 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函数调用的结果将按results
数组的顺序存储在queries
数组中。