【问题标题】:How do I load different partials dynamically using handlebars templates?如何使用车把模板动态加载不同的部分?
【发布时间】:2012-11-15 11:25:21
【问题描述】:

我正在加载包含以下数据的模板:

"slides": [
    {
        "template": "video",
        "data": {
            "video": ""
        }
    },
    {
        "template": "image",
        "data": {
            "image": ""
        }
     }
]

在我的模板中,我想循环播放这些幻灯片,并根据配置的模板加载部分幻灯片

{{#each slides}}
    {{> resources_templates_overlay_video }}
{{/each}}

如何动态地进行部分加载(基于配置的模板)?

我正在使用require-handlebars-plugin

【问题讨论】:

  • 当然也想知道。到目前为止,研究还没有找到解决方案。
  • 2015 年的更新:看起来车把现在支持动态部分。 handlebarsjs.com/partials.html

标签: javascript handlebars.js


【解决方案1】:

我发现上面的答案有点难以理解——它们泄漏了全局变量、具有单字符变量和一些奇怪的命名。所以这是我自己的答案,供我(和你)参考:

使用'hbs'的动态部分,express.js 默认车把实现:

我用这个做了一个简单的博客,把(article-name).md变成/blog/(article-name),创建一个动态部分:

// Create handlebars partials for each blog item
fs.readdirSync('blog').forEach(function(blogItem){
    var slug = blogItem.replace('.md','')
    var fileContents = fs.readFileSync('blog/'+blogItem, 'utf8')
    var html = marked(fileContents)
    var compiledTemplate = hbs.compile(html);
    hbs.registerPartial(slug, compiledTemplate);
})

// Create 'showBlogItem' helper that acts as a dynamic partial
hbs.registerHelper('showBlogItem', function(slug, context, opts) {
    var loadedPartial = hbs.handlebars.partials[slug];
    return new hbs.handlebars.SafeString(loadedPartial(context));
});

这是路线。如果部分不存在则 404s,因为博客不存在。

router.get('/blog/:slug', function(req, res){
    var slug = req.param("slug")
    var loadedPartial = hbs.handlebars.partials[slug];
    if ( ! loadedPartial ) {
        return res.status(404).json({ error: 'Article not found' })
    }
    res.render('blog', {
        slug: slug
    });
})

/views/blog.hbs 看起来像:

<div class="blog">
    {{ showBlogItem slug }}
</div>

【讨论】:

    【解决方案2】:

    据我所知,hbs 期望在编译时知道部分,这是在您传递数据之前。让我们解决这个问题。

    首先,在渲染之前拉入你的动态部分,比如:

    // I required the main template here for simplicity, but it can be anywhere
    var templates = ['hbs!resources/templates/maintemplate'], l = data.slides.length;
    for (var i=0; i<l; i++ )
        templates.push('hbs!resources/templates/overlay/'+data[i].template);
    
    require(templates, function(template) {
        var html = template(data);
    });
    

    并定义一个将充当动态部分的助手

    define(['Handlebars'], function (Handlebars) {
    
        function dynamictemplate(template, context, opts) {
            template = template.replace(/\//g, '_');
            var f = Handlebars.partials[template];
            if (!f) {
                return "Partial not loaded";
            }
    
            return new Handlebars.SafeString(f(context));
        }
    
        Handlebars.registerHelper('dynamictemplate', dynamictemplate);
        return dynamictemplate;
    });
    

    最后,修改你的主模板看起来像

    {{#each slides}}
        {{dynamictemplate this.template this.data}}
    {{/each}}
    

    【讨论】:

    • 不错。尽管我发现很多事情都需要这种解决方法来做非常简单的事情,但总的来说,这真的让我对 Handlebars 感到厌烦。我希望“模板中没有逻辑”的事情不是相当那么死板。
    • @bmoeskau 如果您像我一样厌倦了所有这些无意义的“最佳实践”,请尝试React。它是目前最容易学习的框架,非常棒,它有一种全新的处理方式,它由 Facebook 和一个庞大的社区维护,可以解决你将来遇到、曾经遇到和想要遇到的所有问题.也就是说,我仍在使用 Handlebars 来处理一些响应速度不快的事情,这会让其他人弄乱 HTML —— 这对这个有好处,只有这个,案例。
    • Handlebars.partials[] 似乎返回一个包含原始模板而不是函数的字符串。我假设有一些内部变化?有谁知道现在如何实现这一目标?
    【解决方案3】:

    当Handlebars.partials[] 返回原始字符串时,表示部分未编译。

    我不确定,但我最好的猜测是 Handlebars 在编译包含部分的模板时会在内部编译部分。因此,当您使用帮助器包含部分时,Handlebars 无法识别它并且不会被编译。

    你可以自己compile部分。不要忘记注册已编译的部分,否则每次需要部分时都会编译,这会损害性能。这样的事情应该可以工作。

    var template = Handlebars.partials['templatename'],
        fnTemplate = null;
    
    if (typeof template === 'function') {
      fnTemplate = template;
    } else {
      // Compile the partial
      fnTemplate = Handlebars.compile(partial);
      // Register the compiled partial
      Handlebars.registerPartial('templatename', fnTemplate);  
    }
    
    return fnTemplate(context);
    

    【讨论】:

      猜你喜欢
      • 2016-05-17
      • 1970-01-01
      • 1970-01-01
      • 2021-07-10
      • 2013-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      相关资源
      最近更新 更多