Шаблоны усов: вложенные шаблоны

Как я могу использовать вложенный шаблон внутри усов? Есть ли способ сделать то же самое?

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

Надеюсь, вы поняли вопрос. Я не добавлял escape-символ для корректности js, так как код разбит на разные строки.


person Harry    schedule 27.07.2011    source источник
comment
Почему вы не используете партиалы? mustache.github.io/mustache.5.html#Partials   -  person Pere    schedule 28.07.2016


Ответы (3)


Вы можете использовать лямбду для вложения шаблона:

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);
person marc    schedule 27.07.2011
comment
Я думал об этой работе заранее.. но я думал, что может быть что-то встроенное в усы.. Я могу ошибаться.. - person Harry; 27.07.2011
comment
@Harry: Нет, единственный способ - лямбда-выражения, потому что партиалы не могут получить параметры (за исключением того, что вы их взломаете: stackoverflow.com/questions/6656093/). - person marc; 27.07.2011
comment
Я был бы признателен, если бы вы могли направить меня на какой-нибудь сайт, который дает хорошие знания об усах. - person Harry; 27.07.2011
comment
Извините за беспокойство, но здесь вы в основном повторно реализуете существующую функцию в Mustache. Для этого следует использовать partials; Я делаю это с первого дня, и он будет отображать ваши переменные, как в любом другом обычном стандартном шаблоне. Ты уверен, что правильно используешь частичные выражения, @marc? - person Pere; 28.07.2016
comment
Спасибо за ваш вопрос. Частичные IMO не отвечают на вопросы OP, поскольку они не позволяют передавать аргумент, а полагаются на текущую среду данных. Обратите внимание, что метод в этом ответе позволяет повторно использовать другой шаблон в/различных/контекстах, тогда как частичные могут использоваться только в фиксированном контексте (поскольку они ожидают определенной среды данных, а не получения произвольного аргумента). - person marc; 28.07.2016
comment
Прежде всего, обратите внимание, что здесь мы, кажется, говорим о разных версиях Усов. Как я могу использовать вложенный шаблон в усах?. Это вопрос ОП. Я думаю, что использование частичных ответов отвечает на это. Все еще не понимаю ваших рассуждений. В вашем примере ваш произвольный аргумент исходит из конкретной среды данных, которую вы передаете лямбде. Я хотел бы посмотреть, что в вашем примере нельзя сделать с помощью простого {{>partial}}. - person Pere; 29.07.2016
comment
Поскольку это очень старый вопрос, вполне может быть, что все изменилось :) Трудно сказать, чего хочет ОП, если он не принимает никакого ответа. Но у меня сложилось впечатление, что он спрашивает, как передать аргумент шаблону, {{another_tpl({{name}})}}. Все ответы здесь объясняют, как сделать что-то подобное. Подумайте об общем шаблоне, который используется, например. чтобы текст имел небольшую иконку, чтобы вызвать функцию поиска. Что-то подобное можно использовать с любым текстом, включая текст, сгенерированный с помощью самих усов. Как это будет решено с частичными? - person marc; 29.07.2016

Я сделал пример вложенных шаблонов по адресу jsFiddle. Вот это подробно:

Сначала настройте свой 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>​

Затем 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 );
person Josh    schedule 10.08.2012
comment
Я пошел в том же направлении, за исключением того, что поместил имя подшаблона в шаблон, например {{#nested}}tpl-nested{{/nested}}, см. jsfiddle.net/omnius/env3d7wk, но проблема, с которой я столкнулся, заключалась в том, что это не работало при вложении нескольких уровней, и я не знаю, почему это не работает. т работать. Я думал, что понял, что, поскольку я использовал один и тот же рендерер на всем протяжении, он должен использовать одну и ту же модель данных, которая включает в себя загрузчик подшаблонов. Есть идеи, почему мой Fiddle не выполняет подшаблоны? - person Scott Gartner; 01.02.2017

Вот метод, в котором мы выполняем замену строк перед компиляцией шаблонов. Подшаблоны вызываются в шаблонах следующим образом: {{#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"]);
person Jonathan Chu    schedule 14.02.2013