Mongodb Docpad:通过mongoose回调使用extendTemplateData
我正在尝试构建一个简单的插件,将Mongo中的数据导入一个对象,在渲染时可以在该对象上进行迭代。完整的代码在我的中,但其本质是模拟feedr示例的失败尝试。我知道mongoose的东西在控制台日志工作的同时也在工作,但是将内容发送到docpad对象却让我大吃一惊Mongodb Docpad:通过mongoose回调使用extendTemplateData,mongodb,mongoose,docpad,Mongodb,Mongoose,Docpad,我正在尝试构建一个简单的插件,将Mongo中的数据导入一个对象,在渲染时可以在该对象上进行迭代。完整的代码在我的中,但其本质是模拟feedr示例的失败尝试。我知道mongoose的东西在控制台日志工作的同时也在工作,但是将内容发送到docpad对象却让我大吃一惊 class mongoPlugin extends BasePlugin name: 'mongo' # Fetch list of Gigs getGigsData: (opts) ->
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非常不同,因此我在插件中选择了错误的对象。我可以看到其他人在{}中使用了一个名字,但我不知道这是怎么回事
完成插件代码后,我看到我的数据库数据成为承诺的参数,因此,也许这就是它应该与docpad.config.templateData重新集成的地方,但在实践中似乎不会发生这种情况,因此这里的主要问题是,我们有一个异步函数
getGetsData
在同步函数(模板引擎)中执行。这很简单,是不可能的,因为模板引擎将继续并完成它的工作,而同步工作将在后台进行。这只是一般情况下编写node.js/asynchronous代码的一个问题
解决这个问题相当容易
opts.templateData[“getGigsData”]=@getGigsData()
调用getGigsData
,而不传递opts
,因此当getGigsData
尝试并使用opts时,它无法调用,因此会引发错误。解决方法是执行@getGigsData(opts)
opts.templateData[“getGigsData”]=@getGigsData(opts)
将@getGigsData(opts)
的返回值分配给模板数据,但是,这一操作的结果是db.once
调用的结果,因为这将在该范围内返回。当您执行返回gigs
时,这实际上是gigs.find
调用上(err,gigs)->
回调的返回值,而不是getGigsData
的返回值。这都是关于范围的getGigsData
异步。为此,我们将extendedtemplatedata:(opts)->
更改为extendedtemplatedata:(opts,next)->
以使其异步,并将opts.templateData[“getGigsData”]=@getGigsData()
更改为简单地返回@getGigsData(opts,next)
getGigsData:(opts)->
更改为getGigsData:(opts,next)->
,以接受我们在步骤3中定义的完成回调(next
)。我们将要做的是,我们将调用next,在那里我们有返回gig
,所以让我们将返回gig
更改为返回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
@
太好了。代码需要最后一个next()才能运行。