我创建了一个处理动态助手的外部文件,其中包含一系列我希望能够在所有视图中使用的函数。
在函数中,我正在运行查询并从数据库中获取标记,我想在layout.jade文件中使用它(所有其他视图都在使用)。在控制台中,一切似乎都可以。查询返回标签对象,但由于一些奇怪的原因我无法将对象返回到视图,这给了我一条错误消息,告诉我“标签”未定义“。
这是我的文件dynamicHelpers.js中的代码:
exports.tags = function(req, res){
var environment = require('../environment');
var service = require('../service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
query.exec(function (err, tags) {
if (err) {
console.log(err);
// do something
}
console.log(tags);
return tags;
});
}
在layout.jade中我以这种方式获取对象(这显示未定义):
p
#{tags}
我真正想做的是用'each'遍历所有标签。因此,如果允许并且可能(如果'标签'未定义),后续问题将是什么?
ul.tags
each tag in #{tags}
a(href='/tag/' + tag._id.toHexString())
li.tag= tag.name
更新 我已经尝试了@Linus G Thiel的解决方案(见下文),但无法使其工作(res.tags未定义)。使用中间件中的console.log(标签),它会打印出对象。但是,在下面的dynamicHelper函数中,它是未定义的。似乎res.tags没有因某种原因传递给dynamicHelper。
dynamicHelpers.js:
exports.tags = function(req, res) {
console.log(req.tags); <--- undefined
return req.tags;
};
configuration.js:
module.exports = function(app, express, next){
app.configure(function() {
// lots of more app.use functions (eg. express.cookieParser());)
// ...
app.use(function(req, res, next) {
var environment = require('./environment');
var service = require('./service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
query.exec(function (err, tags) {
if (err) {
return next(err);
}
req.tags = tags;
next();
console.log(req.tags); <--- works fine
});
});
});
};
答案 0 :(得分:4)
正如@Exploit所说in his comment,您的tags
函数会对query.exec
进行异步调用,这将在您的tags
函数返回后完成。 Express'helpers
和dynamicHelpers
不能异步,所以你需要以某种方式重构它。一种方法是将它放在req
的早期中间件或路由中,然后使用一个简单的dynamicHelper
返回:
dynamicHelpers.js:
exports.tags = function(req, res) {
return req.tags;
};
中间件(您可能不希望对所有路由执行此操作,您可以查看例如Route specific middleware或Route param pre-conditions):
app.use(function(req, res, next) {
var environment = require('../environment');
var service = require('../service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
query.exec(function (err, tags) {
if (err) {
return next(err);
}
req.tags = tags;
next();
});
});
答案 1 :(得分:1)
它有点脏,但你可以这样做等待标签设置。 Linus G Thiel提供的解决方案更好,因为这会阻止您的应用程序。
tags: function(req, res) {
var environment = require('../environment');
var service = require('../service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
var _tags = false;
query.exec(function (err, tags) {
if (err) {
console.log(err);
// do something
}
console.log(tags);
_tags = tags;
});
while(_tags == false);
return _tags;
}
你试过这样的吗?
exports = function(app) {
app.dynamicHelpers({
tags: function(req, res) {
var environment = require('../environment');
var service = require('../service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
query.exec(function (err, tags) {
if (err) {
console.log(err);
// do something
}
console.log(tags);
return tags;
});
}
});
}
require("helpers")(app);
答案 2 :(得分:1)
您需要在之前定义中间件
module.exports = function(app, express, next){
app.configure(function() {
app.use(function(req, res, next) {
var environment = require('./environment');
var service = require('./service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
query.exec(function (err, tags) {
if (err) {
return next(err);
}
req.tags = tags;
next();
console.log(req.tags); <--- works fine
});
});
// lots of more app.use functions (eg. express.cookieParser());)
// ...
});
};