返回的对象未定义,使用 dynamicHelpers
Posted
技术标签:
【中文标题】返回的对象未定义,使用 dynamicHelpers【英文标题】:Returned object is undefined, using dynamicHelpers 【发布时间】:2012-05-01 11:07:15 【问题描述】:我创建了一个处理动态帮助器的外部文件,其中包括一堆我希望能够从我的所有视图中使用的函数。
在其中一个函数中,我正在运行查询并从数据库中获取标签,我想在我的 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(tags),它会打印出对象。但是,在下面的 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
);
);
);
;
【问题讨论】:
【参考方案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());)
// ...
);
;
【讨论】:
【参考方案2】:这有点脏,但您可以这样做以等待设置标签。不过,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);
【讨论】:
感谢您的回答。问题是 dynamicHelper 工作正常,所以这不是“需要”问题。只是对象本身好像没有返回。:/ 这可能是因为 query.exec 是异步的,并且函数在查询完成之前返回。 问题是对象在返回之前用 console.log(tags) 打印出来了。 @JasonCraig 它将显示在您的日志语句中,但那是在您的tags
函数返回之后,因为 query.exec
是异步的。【参考方案3】:
正如@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();
);
);
【讨论】:
谢谢!我已经尝试了上面的代码,但我在 req.tags 上未定义? 你在到达的路由之前使用中间件? 是的,至少我是这么认为的。请查看我现在更新的问题,该问题解释了它现在是如何实施的。也许我做错了什么? 尝试在您正在测试的路由中执行console.log
,并查看哪个日志语句先出现。可能是响应后获取标签的情况。
@JasonCraig -- 如果你确实想解决这个问题:如果你有一行app.use(app.router)
,请确保它出现在我的示例中的中间件之后。如果不这样做,请确保在调用configuration
模块之前 调用app.get
、app.post
等等。以上是关于返回的对象未定义,使用 dynamicHelpers的主要内容,如果未能解决你的问题,请参考以下文章