4

可以通过在会话变量更改时重新渲染然后直接操作 DOM 来渲染不同的模板并将它们放置在容器模板中。然而,这并不像 Meteor 的方式。是否有处理 DOM 更新的惯用方式?

客户端.js

if (Meteor.isClient) {

    var getContainerContents = function() {
        console.info('get container contents');
        var active = Session.get('active') == 'foo' ? 'foo' : 'bar';
        return Meteor.render(Template[active]());
    };

    Template.foo.contents = function() {
        console.info('foo contents');
        return 'The foos.';
    };

    Template.bar.contents = function() {
        console.info('bar contents');
        return 'The bars.';
    };

    Meteor.startup(function() {
        console.info('startup');

        Meteor.autorun(function() {
            console.info('autorun');
            $('#container').html(getContainerContents());
        });
    });

}

客户端.html

<head>
  <title>conditional templates</title>
</head>

<body>
  {{> main }}
</body>

<template name="main">
  <section id="container"></section>
</template>

<template name="foo">
  <h2>Foos</h2>
  {{ contents }}
</template>

<template name="bar">
  <h2>Bars</h2>
  {{ contents }}
</template>

更新:也可以为此目的使用模板助手。解决方案是从 template() 函数返回未渲染的字符串内容,并在 Handlebars 中将它们标记为安全,如下所示:

html

<template name="main">
  {{ contents }}
</template>

js

var getContainerContents = function() {
    console.info('get container contents');
    var active = Session.get('active') == 'foo' ? 'foo' : 'bar';
    return Template[active]();
};

Template.main.contents = function() {
    return new Handlebars.SafeString(getContainerContents());
};

// Remove the startup and autorun code. Not necessary now.

有两个问题可能使它不太理想。

  1. 在主模板内呈现的任何嵌套模板也必须标记为 SafeString。否则内容将被 Handlebars 转义。这可能会导致一些膨胀,因为每个嵌套模板都需要 SafeString 代码。
  2. 通过将字符串标记为安全(即未转义),开发人员现在有责任记住在将任何可能不安全的字符串插入页面之前对其进行转义。您拥有的这些越多,就越有可能造成安全漏洞。(有关文档,请参见http://handlebarsjs.com/

所以,在我看来,这个问题仍然悬而未决。但我会听从编辑的意见。

4

3 回答 3

3

使用 Handlebars 条件:

<template name="main">
  {{#if active}}
    {{> foo}}
  {{else}}
    {{> bar}}
  {{/if}}
 </template>

在您的 Meteor JavaScript 代码中:

Template.main.active = function () {
  return Session.get("active");
}

如果 foo 和 bar 共享内容,您可以使用 Helper,或者让 foo 和 bar 使用相同的部分(即。

{{> 内容}}

) 取决于您的需要。

于 2012-12-25T03:46:41.150 回答
1

这是我正在使用的设置

客户端/client.js

Template.page.display_content = function () {
    var page_index = Handlebars.Utils.escapeExpression(Session.get('page'));

    if (Template[page_index]) {
        return Template[page_index]();
    } else {
        return Template['page_not_found']();
    }
};

客户端/template.html

<template name="page">
    {{{display_content}}}
</template>

我只需要执行 Session.set("page", "xyz") 来更改页面,并且由于{{{它会自动标记为 SafeString。

1.模板“xyz”内的嵌套模板不需要标记为SafeString,它们都是在转义之前渲染的

到 2. 你不必这样做,因为如果你输出一些像 {{text}} 这样的数据,它会再次自动转义,它不会再次被转义

于 2012-12-25T10:57:55.157 回答
0

您使用存储在公开变量(在模板助手中)中的名称引用模板:

{{> Template.dynamic template=varHandlingTemplateName }}

这是 meteorjs 在其最新版本(截至今天)中解决动态模板情况的方式。

问候,格雷格

于 2015-11-06T15:42:28.123 回答