2012-10-19 52 views
20

我希望能够在不明确指定模板的情况下动态加载模板。在Meteor.js中动态加载模板

举个例子:

<template name="foo"> 
</template> 

其中“富”是模板,我想通过调用一些方法动态加载能力:

Meteor.render(Meteor.loadTemplate('foo')); 

这可能吗?

回答

13

流星0.9.x版本的新API

达恩·达斯卡莱斯卡指出流星现在已经内置了动态模板!这很好,因为你不需要像在以前的版本中看到的那样包含额外的代码。

{{> Template.dynamic template=template [data=data] }} 

流星0.8.4传统

动态模板没有数据:鲍里斯·科托夫的更新火焰(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'); 
    } 
}); 
+3

在此期间API已更改。现在推荐的方法是使用http://docs.meteor.com/#template_dynamic –

7

您已经找到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. 
}); 

然后片段是你的反应片段,让你的模板可以继续接收实时更新。您的片段现在需要在网页中(我使用jQuery,所以这个例子,以及)将:

$("#htmlnode").html(fragment); 

$(“#htmlnode”)只是在你的DOM,你要渲染的模板的一个节点。你现在已经在你的网页上呈现了内容。

+0

这对我有一些小的变化。因为我用div标签包围了模板中的元素,所以使用上面的代码呈现了一个未定义的片段。调用Meteor.render(Template [templateName])来解决这个问题。 – chimon2000

+0

为了防止任何人遇到代码问题,您可能需要先检查模板是否可以在调用之前先用“if(Template [templateName])”访问。 – Dave

+0

非常正确的戴夫。如果模板不存在,我倾向于向控制台发送消息,这样我就可以马上知道是否使用了错误的名称等。 – Joc

2

我只是做这样的,没有jQuery的要求:

EDITED

Template.mainContent.showContentFromRouter = function() { 
    return Template[Meteor.Router.page()](); 
}; 

在这种情况下,我使用流星路由器,并返回我选择的任何模板(从路由器),但你可能只是这样做:

Template.mainContent.showDynamicContent = function() { 
    return Template['someTemplateYouveDefined'](); 
}; 
+0

当我尝试这个标记时,标记在页面上显示为一个字符串。你如何解决这个问题? – Samo

+2

您在模板中的{{showContentFromRouter}}事物周围添加额外的{}。像这样:{{{showContentFromRouter}}}。这个HTML-转义字符串。 @Samo –

+0

这个解决方案的问题在于,只要showDynamicContent函数被调用,模板就会一次又一次地在内存中生成。有没有办法从内存中删除模板?我用这种方法测试了1000多个子模板,并且几次来​​回移除它们。 –

0

流星0.8.4传统

使用Joc's答案为指导, 我已经使用http://docs.meteor.com/#template_call实现类似,但使用的辅助,而不是作为建议的文档:

当模板帮手内部调用,流星体。渲染或其他设置,生成反应式HTML时,生成的HTML将被注释为使其呈现为反应性DOM元素

我的客户端。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> 
+0

这是过时的 - 请参阅[我的答案](http://stackoverflow.com/a/26421763/1269037) –

2

更新大火:

https://github.com/meteor/meteor/wiki/Using-Blaze#templatefoo-is-not-a-function-and-does-not-return-a-string

动态呈现给定的数据上下文模板

旧:

{{dynamicTemplate name="templateName" data=dataContext}} 

Template.foo.dynamicTemplate = function (opts) { 
    return Template[opts.name](opts.data); 
}; 

新:(值得注意的是,在火焰,关键字参数包含或块助手都捆绑到它成为新的数据上下文单个对象)

{{> 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]; 
} 

顺便说一句,我真的不与它一起玩,但这是我从新的火焰文件采取的。所以,我觉得应该是这样做的方式;)

+0

你是什么意思与上下文?你有没有想过名称=“templateNAME”? – ncubica

+1

是的,正确的。在这种情况下,Id是模板的标识符或模板的名称。上下文变量是您放入模板的内容。希望能帮助到你。 –

+0

你如何或在哪里设置ID和上下文? –

-1

基于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> 

编辑 在流星中不起作用0.8.0

+0

这已经过时 - 请参阅[我的答案](http://stackoverflow.com/a/26421763/1269037)和https://github.com/meteor/meteor/issues/2836关于直接分配到'Template.foo '。 –

-1

对我来说最简单的方法就是创建一个函数get_ dynamic_template,所以像:

var a= get_dynamic_template(template_name,data); 

返回什么可以呈现为一个正常的变量{{一}}

这个函数的代码非常简单:

var get_dynamic_template = function(template_name,data) 
{ 

     return function(){ 
     return new Handlebars.SafeString(
      UI.toHTML(
       Template[template_name].extend({data: function() { return data; }})) 
     ); 
     }; 

} 
+0

推荐的方法是http://docs.meteor.com/#template_dynamic –

-1

这将HANDL动态模板具有和不具有数据: (需要布拉/流星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]; 
}; 
+0

这已经过时 - 请参阅[我的答案](http://stackoverflow.com/a/26421763/1269037)。 –

0

https://github.com/meteor/meteor/wiki/Using-Blaze

{{> post}} 

Template.foo.helpers({ 
    post: function() { 
    return Template[this.postName]; 
    } 
}); 

模板包含现在搜索模板对象的助手和数据的名称空间,因此可以通过编程方式轻松选择要使用的模板。这是一个强大的功能,并允许将模板分配为另一个模板的模板,以便可以覆盖模板。

+0

谢谢!我已经删除了弃用的代码。 (但这不是推荐的解决方案。) –

36

从Meteor 0.9.4 - 1.0开始,下面是动态呈现模板的方法。在撰写本文时,所有其他答案都已过时。

假设您正在编辑一堆记录或创建一个新记录,并且想要根据某些Session变量渲染update模板或new模板。

有两种方法可以做到这一点:

1)这是流星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)此功能各种流星版本,但不是正式推荐,因为目前还不清楚模板是否是动态选择的:

<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}} 
+1

Woooowww。非常感谢!!!我从来没有明白这一点...... –

+1

这是正确的方法 –

+1

这是现在最流行的答案,但我建议展示如何选择性地将数据传递给作用域。 {0> Template.dynamic template = whichOne data = myData}} – Turbo