我正在使用以下数据加载模板:
"slides": [
{
"template": "video",
"data": {
"video": ""
}
},
{
"template": "image",
"data": {
"image": ""
}
}
]
在我的模板中,我想循环遍历这些幻灯片,并根据配置的模板,我想加载部分
{{#each slides}}
{{> resources_templates_overlay_video }}
{{/each}}
如何动态(基于配置的模板)进行部分加载?
答案 0 :(得分:15)
据我所知,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}}
答案 1 :(得分:3)
我发现上面的答案有点难以理解 - 它们泄漏全局变量,有单个字符变量,还有一些奇怪的命名。所以这是我自己的答案,对于我(和你)的参考:
动态部分使用&#39; hbs&#39;,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 :(得分:2)
当Handlebars.partials[]
返回原始字符串时,表示不编译部分。
我不确定,但最好的猜测是Handlebars在编译包含partial的模板时会在内部编译部分。因此,当您使用帮助程序来包含部分时,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);