javascript Mustache 模板:嵌套模板

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6846672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 22:04:24  来源:igfitidea点击:

Mustache Templating: nested templates

javascripttemplate-enginemustache

提问by Harry

How can I use a nested template within mustache? Is there a way to do the same?

如何在 mustache 中使用嵌套模板?有没有办法做同样的事情?

var tmpl="{{#data}} 
{{values}}
Name: {{name}}
//{{another_templ({{name.value}})}}
{{/values}}
{{/data}}"

Hope you guys got the question. I have not added the escape character for js validity since code is split across different lines.

希望大家答疑解惑。我没有为 js 有效性添加转义字符,因为代码被分成不同的行。

回答by marc

You could use a lambda to nest the template:

您可以使用 lambda 来嵌套模板:

function nested_template(template_string, translate) {
  return function() {
    return function(text, render) {
      return Mustache.to_html(template_string, translate(render(text)));
    };
  };
}

var template_string = 
  "{{#data}}"+
    "{{values}}"+
      "Name: {{name}}"+
      "{{#another_templ}}{{name}}{{/another_templ}}"+
    "{{/values}}"+
  "{{/data}}";

var another_template_string = "<b>{{name}}</b>"; // for example

var view = {
  data: {
    values: {
      name: "Test"
    }
  },
  another_templ: nested_template(another_template_string, function(text) {
    return {name: text};
  });
};

var result = Mustache.to_html(template_string, view);

回答by Josh

I have made an example of nested templates over at jsFiddle. Here it is in detail:

我在jsFiddle做了一个嵌套模板的例子。这里有详细介绍:

First, set up your HTML

首先,设置你的 HTML

<div class="main"><!-- content here --></div>

<script type="text/html" id="tpl">
    {{#data}}
        {{#names}}
            Name: {{name}}
            {{#nested}}{{name}}{{/nested}}<br>
        {{/names}}
    {{/data}}
</script>

<script type="text/html" id="tpl-nested">
    &mdash; <b>{{name}}</b>
</script>?

Then the javascript (using jQuery)

然后是 javascript(使用 jQuery)

function renderNested(template_string, translate) {
    return function() {
        return function(text, render) {
            return Mustache.to_html(template_string, translate(render(text)));
        };
    };
}

var template = $("#tpl").html();

var nested_template = $("#tpl-nested").html();

var model = {
    data: {
        names: [
            { name: "Foo" },
            { name: "Bar" }
        ],
        nested: renderNested(nested_template, function(text) {
            return { name: text };
        })
    }
};

var result = Mustache.to_html(template, model);

$(".main").html( result );

回答by Jonathan Chu

Here is a method where we do string replacement before we compile the templates. Subtemplates are called in the templates by: {{#template}}insertTheNameOfYourSubTemplateHere{{/template}}

这是一种在编译模板之前进行字符串替换的方法。子模板通过以下方式在模板中调用:{{#template}} insertTheNameOfYourSubTemplateHere{{/template}}

templates = {}

function compileTemplates(templateNamesArray) {
    for (index in templateNamesArray) {
        var templateName = templateNamesArray[index];
        var baseHTML = $('#' + templateName).html();

        var start = baseHTML.indexOf("{{#template}}");
        while(start != -1) {
            var end = baseHTML.indexOf('{{/template}}', start);
            var nestedTemplateName = baseHTML.slice(start + "{{#template}}".length, end);
            var nestedTemplateEl = $('#' + nestedTemplateName);
            if (nestedTemplateEl.length == 0) {
                throw "Could not find nested template '" + nestedTemplateName + "' for the template '" + templateName + "'";
            }
            baseHTML = baseHTML.slice(0, start) + nestedTemplateEl.html() + baseHTML.slice(end + '{{/template}}'.length);
            start = baseHTML.indexOf("{{#template}}", start);
        }
        templates[templateName] = Handlebars.compile(baseHTML);
    }
}

compileTemplates(["templateActiveThreadTab", "templateActiveThreadContent", "templateTodoItem"]);