在Meteor.js中dynamic加载模板
我希望能够dynamic加载模板,而不显式指定模板。
举个例子:
<template name="foo"> </template>
其中'foo'是模板,我想通过调用一些方法dynamic加载它的能力:
Meteor.render(Meteor.loadTemplate('foo'));
这可能吗?
meteor0.9.x新的API
Dan Dascalescu指出,meteor现在已经内置了dynamic模板! 这很好,因为你不需要像以前的版本那样包含额外的代码。
{{> Template.dynamic template=template [data=data] }}
对于Meteor 0.8.x Legacy
没有数据的dynamic模板: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] }; };
我希望有一个更简单的解决scheme,但我需要将模板包装在JSON中,如图所示。 也许这会帮助别人前进。
dynamic模板与数据:如果你有,并希望数据是dynamic的,一定要做一个辅助方法,可以作出反应。 请确保在某处执行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'); } });
以下是如何dynamic呈现模板,从Meteor 0.9.4 – 1.0开始。 所有其他答案在撰写本文时已经过时了。
假设您正在编辑一堆logging或创build一个新logging,并且想要根据某些Sessionvariables呈现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版本,但不是正式推荐,因为不清楚模板是否是dynamicselect的:
<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}}
你已经findMeteor.render,但你缺less的是模板加载。 在文档中提到你可以调用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. });
然后片段是您的Reactive片段,以便您的模板可以继续接收实时更新。 你的片段现在需要放置在网页(我使用jQuery,所以这个例子也是如此):
$("#htmlnode").html( fragment );
$(“#htmlnode”)只是您想要模板呈现的DOM中的一个节点。 你现在已经在你的网页上呈现内容了。
我只是这样做,不需要jQuery:
EDITED
Template.mainContent.showContentFromRouter = function() { return Template[Meteor.Router.page()](); };
在这种情况下,我使用meteor路由器,并返回我select的任何模板(从路由器),但你可以这样做:
Template.mainContent.showDynamicContent = function() { return Template['someTemplateYouveDefined'](); };
火焰更新:
使用给定的数据上下文dynamic呈现模板
旧:
{{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]; }
顺便说一句,我真的没有玩过,但这是我从新的火焰文件。 所以我觉得应该是这样做的方法;)
从https://github.com/meteor/meteor/wiki/Using-Blaze
{{> post}} Template.foo.helpers({ post: function () { return Template[this.postName]; } });
模板包含现在search模板对象的助手名称空间和数据,因此可以通过编程方式轻松select要使用的模板。 这是一个强大的function,并将允许模式,如分配一个模板作为另一个帮助,以便它可以被覆盖。
meteor0.8.x遗产
使用Joc的答案作为指导,我已经实现类似的使用http://docs.meteor.com/#template_call ,但使用帮手,而不是文档build议的:
当在模板帮助器,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>
根据Hillmark的回答,这是最容易得到的:
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中不起作用
对我来说,最简单的方法就是创build一个函数get_dynamic_template,如下所示:
var a= get_dynamic_template(template_name,data);
返回可以呈现为普通variables{{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; }})) ); }; }
这将处理有和没有数据的dynamic模板:(需要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]; };