首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Docpad:通过mongoose回调使用extendTemplateData

Docpad:通过mongoose回调使用extendTemplateData
EN

Stack Overflow用户
提问于 2014-02-14 14:07:38
回答 1查看 91关注 0票数 0

我正在尝试构建一个简单的插件来从Mongo获取数据到一个对象中,我可以在渲染时在这个对象上进行迭代。完整的代码在我的project中,但它的本质是一次模拟feedr示例的失败尝试。我知道mongoose内容可以像控制台日志一样工作,但是将内容发送到docpad对象会让我感到困惑。

代码语言:javascript
复制
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重新集成的地方,但在实践中似乎并没有发生这种情况

EN

回答 1

Stack Overflow用户

发布于 2014-02-15 00:58:33

所以这里的主要问题是我们有一个异步函数getGetsData在一个同步函数中执行,你的模板引擎。这是不可能的,因为模板引擎将继续执行它的事情,而同步的东西在后台发生。一般来说,这只是一个编写node.js/异步代码的问题。

解决这个问题的方法非常简单。

  1. opts.templateData["getGigsData"] = @getGigsData()在不传递opts的情况下调用getGigsData,因此当getGigsData尝试使用opts时,它无法调用,因此会抛出错误。解决这个问题的方法是执行@getGigsData(opts)
  2. opts.templateData["getGigsData"] = @getGigsData(opts)@getGigsData(opts)的返回值分配给模板数据,但是,结果是db.once调用的结果,因为这将在该作用域中返回。执行return gigs时,这实际上是Gigs.find调用的(err, gigs) ->回调的返回值,而不是getGigsData的返回值。这都是关于作用域的。
  3. 因为数据库的东西是异步的,所以我们需要让getGigsData异步。为此,我们将extendTemplateData: (opts) ->更改为extendTemplateData: (opts,next) ->以使其成为异步的,并将opts.templateData["getGigsData"] = @getGigsData()更改为简单的return @getGigsData(opts,next)
  4. Now,即我们拥有事件并调用异步。我们现在需要让getGigsData的定义支持它。因此,让我们将getGigsData: (opts) ->更改为getGigsData: (opts,next) ->,以接受我们在步骤3中定义的完成回调(next)。接下来,我们将调用return gigs所在的位置,因此,让我们将return gigs更改为return next()
  5. It现在应该可以工作了。但作为一点清理,我们可以通过将if err then console.error "db error"更改为return next(err) if err来更好地处理错误。您需要修复缩进,因为我们将需要删除else块。

考虑到所有这些,并应用了更多的清理,您最终将得到以下结果:

代码语言:javascript
复制
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
        @
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21772015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档