我希望能够在不明确指定模板的情况下动态加载模板。
举个例子:
<template name="foo">
</template>
其中'foo'是模板,我希望能够通过调用一些方法来动态加载它:
Meteor.render(Meteor.loadTemplate('foo'));
这可能吗?
我希望能够在不明确指定模板的情况下动态加载模板。
举个例子:
<template name="foo">
</template>
其中'foo'是模板,我希望能够通过调用一些方法来动态加载它:
Meteor.render(Meteor.loadTemplate('foo'));
这可能吗?
以下是从 Meteor 0.9.4 - 1.0 开始动态渲染模板的方法。在撰写本文时,所有其他答案都已过时。
假设您正在编辑一堆记录,或者创建一个新记录,并且想要根据一些 Session 变量呈现update
模板或模板。new
有两种方法可以做到这一点:
1) 这是Meteor 0.9.4 或更新版本的官方推荐方法- 它使用Template.dynamic
:
<template name="records">
{{> Template.dynamic template=whichOne}}
</template>
<template name="recordUpdate">
...
</template>
<template name="recordNew">
...
</template>
Template.records.helpers({
whichOne: function () {
return Session.get('edit') ? 'recordUpdate' : 'recordNew'
// note that we return a string - per http://docs.meteor.com/#template_dynamic
}
});
2) 这适用于各种 Meteor 版本,但不推荐正式使用,因为不清楚模板是动态选择的:
<template name="records">
{{> whichOne}}
</template>
{{! Note how "whichOne" is indistinguishable from a constant template name... }}
{{ ...like "recordUpdate" or "recordNew" below. }}
<template name="recordUpdate">
...
</template>
<template name="recordNew">
...
</template>
Template.records.helpers({
whichOne: function () {
return Session.get('edit') ? Template.recordUpdate : Template.recordNew
// note that we return a Template object, not a string
}
});
要将数据上下文传递给模板,请使用:
{{> Template.dynamic template=whichOne data=myData}}
Meteor 0.9.x 新 API
Dan Dascalescu 指出 Meteor 现在有内置的动态模板!这很好,因为您不需要包含以前版本中看到的额外代码。
{{> Template.dynamic template=template [data=data] }}
Meteor 0.8.x 旧版
没有数据的动态模板:Boris Kotov 更新的 Blaze (0.8.0) 答案在正确的轨道上(取自最新文档),但它对我来说不起作用。我得到了以下工作:
{{> dynamicTemplate name=myDynName}}
<template name="dynamicTemplate">
{{#with chooseTemplate name}}
{{> template}}
{{/with}}
</template>
Template.dynamicTemplate.chooseTemplate = function (name) {
return { template: Template[name] };
};
我希望有一个更简单的解决方案,但我需要将模板包装在 JSON 中,如图所示。也许这会帮助其他人继续前进。
带有数据的动态模板:如果您拥有并且希望数据是动态的,请务必创建一个可以做出反应的辅助方法。请务必在某处执行 Session.set() 以查看效果。
// Inside "myContainingTemplate"
{{> dynamicTemplateWithData name=myDynName data=myDataHelper}}
<template name="dynamicTemplateWithData">
{{#with chooseTemplate name}}
{{#with ../data}}
{{> ..}}
{{/with}}
{{/with}}
</template>
Template.dynamicTemplateWithData.chooseTemplate = function (name) {
return Template[name];
};
Template.myContainingTemplate.helpers({
myDataHelper: function () {
Session.get('myReactiveKey');
}
});
您已经找到 Meteor.render 但您缺少的是模板加载。在文档中它提到您可以调用 Template.foo() 来返回模板的 HTML。
http://docs.meteor.com/#template_call
将它们放在一起,您可以访问模板 foo 或任何其他使用括号访问的模板,因此:
var templateName = "foo";
var fragment = Meteor.render( function() {
return Template[ templateName ](); // this calls the template and returns the HTML.
});
那么fragment就是你的Reactive Fragment,这样你的模板就可以继续接收实时更新。您的片段现在需要放置在网页中(我使用 jQuery,所以这个示例也是如此):
$("#htmlnode").html( fragment );
$("#htmlnode") 只是 DOM 中的一个节点,您希望在其中呈现模板。现在,您的网页中就有了渲染的内容。
我只是这样做,不需要jQuery:
已编辑
Template.mainContent.showContentFromRouter = function() {
return Template[Meteor.Router.page()]();
};
在这种情况下,我使用 Meteor 路由器,并返回我选择的任何模板(从路由器),但你可以这样做:
Template.mainContent.showDynamicContent = function() {
return Template['someTemplateYouveDefined']();
};
火焰更新:
动态呈现具有给定数据上下文的模板
老的:
{{dynamicTemplate name="templateName" data=dataContext}}
Template.foo.dynamicTemplate = function (opts) {
return Template[opts.name](opts.data);
};
新:(值得注意的是,在 Blaze 中,包含或块助手的关键字参数被捆绑到成为新数据上下文的单个对象中)
{{> dynamicTemplate name="templateName" data=dataContext}}
<template name="dynamicTemplate">
{{#with chooseTemplate name}}
{{#with ../data}} {{! original 'data' argument to DynamicTemplate}}
{{> ..}} {{! return value from chooseTemplate(name) }}
{{/with}}
{{/with}}
</template>
Template.dynamicTemplate.chooseTemplate = function (name) {
return Template[name];
}
顺便说一句,我并没有真正玩过它,但这是我从新的 blaze 文档中得到的。所以我认为这应该是这样做的方法;)
Meteor 0.8.x 旧版
使用Joc 的回答作为指导,我使用http://docs.meteor.com/#template_call实现了类似的效果,但使用了帮助器,如文档所建议的那样:
当在模板助手、Meteor.render 的主体或正在生成响应式 HTML 的其他设置中调用时,生成的 HTML 会被注释,以便它呈现为响应式 DOM 元素
我的 client.js 看起来有点像这样:
Template.myPageTemplate.helpers({
dynamicTemplate: function() {
// conditional logic can be added here to determine which template to render
return Template.myDynamicTemplate();
}
});
我的 html 看起来像这样:
<template name="myPageTemplate">
<h1>My Template</h1>
{{{dynamicTemplate}}}
</template>
<template name="myDynamicTemplate">
<h1>My Dynamic Template</h1>
</template>
来自https://github.com/meteor/meteor/wiki/Using-Blaze
{{> post}}
Template.foo.helpers({
post: function () {
return Template[this.postName];
}
});
模板包含现在在帮助器和数据的命名空间中搜索模板对象,因此很容易以编程方式选择要使用的模板。这是一个强大的功能,并且将允许将一个模板分配为另一个模板的助手等模式,以便可以覆盖它。
根据希尔马克的回答,这是最容易得到的:
Template.main.template = function() {
if (some_condition) {
return Template.A();
} else {
return Template.B();
}
};
用对应的.html
<body>
{{> main}}
</body>
<template name="main">
{{{template}}}
</template>
<template name="A">
<h1>Template A</h1>
</template>
<template name="B">
<h1>Template B</h1>
</template>
编辑 在 Meteor 0.8.0 中不起作用
对我来说,最简单的方法就是创建一个函数 get_dynamic_template,如下所示:
var a= get_dynamic_template(template_name,data);
它返回可以呈现为普通变量 {{a}} 的内容
这个函数的代码很简单:
var get_dynamic_template = function(template_name,data)
{
return function(){
return new Handlebars.SafeString(
UI.toHTML(
Template[template_name].extend({data: function () { return data; }}))
);
};
}
这将处理有数据和无数据的动态模板:(需要 Blaze/Meteor 0.8)
{{> dynamicTemplate name=templateName}}
<template name="dynamicTemplate">
{{#with chooseTemplate name }}
{{#if ../data}}
{{#with ../data }}
{{> .. }}
{{/with}}
{{else}}
{{> this}}
{{/if}}
{{/with}}
<template name="dynamicTemplate">
模板 javascript:
Template.dynamicTemplate.chooseTemplate = function (name) {
return Template[name];
};