在Meteor.js中动态加载模板

时间:2012-10-19 06:46:55

标签: javascript meteor

我希望能够动态加载模板而无需明确指定模板。

举个例子:

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

其中'foo'是模板,我希望能够通过调用某种方法动态加载它:

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

这可能吗?

10 个答案:

答案 0 :(得分:36)

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

我们假设您正在编辑一堆记录或创建一个新记录,并且希望基于以下内容呈现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}}

答案 1 :(得分:13)

Meteor 0.9.x新API

Dan Dascalescu指出Meteor现在内置了动态模板!这很好,因为您不需要包含以前版本中的额外代码。

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

适用于Meteor 0.8.x Legacy

动态模板没有数据: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');
    }
});

答案 2 :(得分: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.
});

然后片段是您的Reactive片段,以便您的模板可以继续接收实时更新。你的片段现在需要放在网页中(我使用jQuery,所以这个例子也是如此):

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

$(“#htmlnode”)只是DOM中您想要渲染模板的节点。现在,您已在网页中显示了已呈现的内容。

答案 3 :(得分:2)

我只是这样做,不需要jQuery:

<强> EDITED

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

在这种情况下,我正在使用Meteor路由器,并返回我选择的任何模板(来自路由器),但你可以这样做:

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

答案 4 :(得分: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);
};

新:(值得注意的是,在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];
}

顺便说一下,我并没有真正玩过它,但这是我从新的火焰文档中获取的。所以我认为它应该是这样做的方式;)

答案 5 :(得分:0)

流星0.8.x遗产

使用Joc's答案作为指导, 我使用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>

答案 6 :(得分:0)

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

{{> post}}

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

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

答案 7 :(得分:-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>

修改 不适用于Meteor 0.8.0

答案 8 :(得分:-1)

对我来说最简单的方法是创建一个函数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; }}))
          );
      };

}

答案 9 :(得分:-1)

这将使用和不使用数据来处理动态模板: (需要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];
};