我正在尝试构建一个简单的插件来从Mongo获取数据到一个对象中,我可以在渲染时在这个对象上进行迭代。完整的代码在我的project中,但它的本质是一次模拟feedr示例的失败尝试。我知道mongoose内容可以像控制台日志一样工作,但是将内容发送到docpad对象会让我感到困惑。
class mongoPlugin extends BasePlugin
name: 'mongo'
# Fetch list of Gigs
getGigsData: (opts) ->
mongoose.connect ('mongodb://localhost/test')
db = mongoose.connection;
db.on 'error', console.error.bind(console, 'connection error:')
db.once 'open', () ->
gigsSchema = mongoose.Schema {
date : String,
location : String
}
Gigs = mongoose.model 'Gigs', gigsSchema
Gigs.find {}, (err, gigs) ->
mongoose.connection.close()
if err then console.error "db error"
else
console.dir gigs
opts["getGigsData"] = gigs
opts.templateData["getGigsData"] = gigs
return gigs
extendTemplateData: (opts) ->
opts.templateData["getGigsData"] = @getGigsData()使用节点检查器并通过编辑docpad.coffee触发重新生成,我可以看到opts有一个字段templateData,但它是空的,并且与docpad.templateData非常不同,所以我在插件中选择了错误的对象。我可以看到其他人做了一个把戏,把名字放在{}中,但我不知道这是做什么。
完成插件代码后,我发现我的数据库数据变成了promise的参数,所以也许这就是它应该与docpad.config.templateData重新集成的地方,但在实践中似乎并没有发生这种情况
发布于 2014-02-15 00:58:33
所以这里的主要问题是我们有一个异步函数getGetsData在一个同步函数中执行,你的模板引擎。这是不可能的,因为模板引擎将继续执行它的事情,而同步的东西在后台发生。一般来说,这只是一个编写node.js/异步代码的问题。
解决这个问题的方法非常简单。
opts.templateData["getGigsData"] = @getGigsData()在不传递opts的情况下调用getGigsData,因此当getGigsData尝试使用opts时,它无法调用,因此会抛出错误。解决这个问题的方法是执行@getGigsData(opts)opts.templateData["getGigsData"] = @getGigsData(opts)将@getGigsData(opts)的返回值分配给模板数据,但是,结果是db.once调用的结果,因为这将在该作用域中返回。执行return gigs时,这实际上是Gigs.find调用的(err, gigs) ->回调的返回值,而不是getGigsData的返回值。这都是关于作用域的。getGigsData异步。为此,我们将extendTemplateData: (opts) ->更改为extendTemplateData: (opts,next) ->以使其成为异步的,并将opts.templateData["getGigsData"] = @getGigsData()更改为简单的return @getGigsData(opts,next)getGigsData: (opts) ->更改为getGigsData: (opts,next) ->,以接受我们在步骤3中定义的完成回调(next)。接下来,我们将调用return gigs所在的位置,因此,让我们将return gigs更改为return next()if err then console.error "db error"更改为return next(err) if err来更好地处理错误。您需要修复缩进,因为我们将需要删除else块。考虑到所有这些,并应用了更多的清理,您最终将得到以下结果:
class mongoPlugin extends BasePlugin
name: 'mongo'
config:
hostname: 'mongodb://localhost/test'
# Fetch list of Gigs
getGigsData: (opts={}, next) ->
config = @getConfig()
docpad = @docpad
mongoose.connect(config.hostname)
db = mongoose.connection
db.on 'error', (err) ->
docpad.error(err) # you may want to change this to `return next(err)`
db.once 'open', ->
gigsSchema = mongoose.Schema {
date: String,
location: String
}
Gigs = mongoose.model('Gigs', gigsSchema)
Gigs.find {}, (err, gigs) ->
mongoose.connection.close()
return next(err) if err
return next(null, gigs)
# Chain
@
extendTemplateData: (opts,next) ->
@getGigsData null, (err, gigs) ->
return next(err) if err
opts.templateData.gigs = gigs
# Chain
@https://stackoverflow.com/questions/21772015
复制相似问题