underscore.js вложенные шаблоны - PullRequest
44 голосов
/ 20 января 2012

Можно ли каким-то образом взять элемент DOM из шаблона подчеркивания и использовать его в качестве другого шаблона?

Идея состоит в том, что моему приложению необходимо отобразить документ, который содержит цикл с элементами и сводкой.Время от времени мне нужно перерисовывать только сводку или несколько элементов, поэтому я не могу просто перерисовать весь документ.

Однако я бы хотел, чтобы пользователи приложения могли легко создавать свои собственные шаблоны.для документа, и я думаю, что хранить все в одном файле для документа будет проще.

Я пытаюсь использовать что-то вроде этого:

<script type="text/template" id="document-template">
    <div id="document">
        <h1><%= name %></h1>
        <ul class="items">
            <% _.each(items, function(item) { %> 
                <li><%= item %></li>
            <% }); %>
        </ul>
        <div id="summary">
            <p>Total items: <%= totalitems %></p>
        </div>
    </div>
</script>

Теперь я могу легкосделайте это var documentTemplate = _.template($('#document-template').html());, чтобы превратить его в шаблон документа, но я бы хотел превратить итоговую часть в шаблон, а элемент списка в шаблон.

Могу ли я сделать что-то вроде этого:

var summaryTemplate = _.template($('#document-template #summary').html());
var itemTemplate = _.template($('#document-template .items li').html());

PS.На самом деле я загружаю шаблон из внешнего файла, используя $ .get jQuery.Таким образом, я получу шаблон документа в одну большую строку.Оттуда я могу сделать только documentTemplate = _.template(loadedString);.

Теперь, если бы я мог просто извлечь элемент #summary из строки, он должен работать.Но когда я пытаюсь преобразовать строку в элемент DOM (var domElement = $(loadedString)) (чтобы я мог сделать это: summaryTemplate = _.template($('#summary',domElement).html());, это не сработает, потому что подчеркивание больше не распознает теги <% =%>.

Ответы [ 4 ]

66 голосов
/ 30 ноября 2012

Вы можете передать вложенный шаблон как переменную в назначениях шаблонов в основной шаблон, например:

HTML:

<script type="text/template" id="sub_template">
  <article>
    <h1>id: <%= id %><h1>
  </article>
</script>

<script type="text/template" id="main_template">
  <% for (var i = 0; i < num; i++) { %>
    <%= renderSub({id:i}) %>
  <% } %>
</script>

JS:

 var renderSub = _.template( $('#sub_template').remove().text() ),
     renderMain = _.template( $('#main_template').remove().text() );

  renderMain({num:5, renderSub:renderSub});
5 голосов
/ 08 апреля 2014

Детская площадка

/////// TEMPLATES //////

    var mainTemplate = "<ul> \
                          <% _.each(items, function(item) { %> \
                               <%= listItem({item:item}) %> \
                          <% }); %> \
                        <ul>";

    var subTemplate = '<li><%=item %></li>';


/////// MODEL (our data) //////

    var model = {
        items : [1,2,3,4,5]
    }


/////// COMPILE //////

    // add the subTemplate to the model data, to be passed to the mainTemplate
    model.listItem = _.template(subTemplate);

    // Render main template to the DOM
    document.body.innerHTML = _.template(mainTemplate, model);
2 голосов
/ 06 октября 2012

Вместо того, чтобы загружать все сразу как один шаблон, а затем пытаться загрузить его часть позже, разделите их как несколько шаблонов.

Имейте свой основной шаблон документа и итоговый шаблон.Начальная загрузка извлекает шаблон документа, а затем извлекает шаблон резюме и вставляет его в скомпилированный DOM из первого шаблона.Затем вы можете перезагрузить второй шаблон в любое время.См. Следующие шаги:

1) Загрузите исходный шаблон, как показано ниже:

<script type="text/template" id="document-template">
    <div id="document">
        <h1><%= name %></h1>
        <ul class="items">
            <% _.each(items, function(item) { %> 
                <li><%= item %></li>
            <% }); %>
        </ul>
    </div>
</script>

2) После того, как это скомпилировано в DOM, загрузите второй шаблон с подчеркиванием, как показано ниже:

<script type="text/template" id="summary-template">
    <div id="summary">
        <p>Total items: <%= totalitems %></p>
    </div>
</script>

3) Вызовите $ ("# document"). Append (summaryTemplate) или любую другую переменную, содержащую скомпилированный шаблон.

4) Повторите шаги 2 и 3 в любое время, когда вам нужнодля перезагрузки сводки, за исключением того, что сначала удалите существующий $ ("# summary") перед повторным добавлением

Вы можете использовать эту же стратегию и для элементов, просто убедитесь, что вы используете правильные селекторы / методы jQuery, чтобычто вы перезаписываете существующие div в правильном порядке, так как append будет работать только для добавления чего-либо в конец элемента.

1 голос
/ 17 ноября 2015

Я знаю, что я опоздал на беседу на 3 года, но ни один из этих ответов вообще не относится к ситуации, которая была у меня в моем последнем проекте.И поскольку то, как я изначально думал о том, чтобы сделать это, в конечном итоге сработало, я решил опубликовать его на тот случай, если кто-то захочет на самом деле вложить шаблоны underscore.js, как говорится в заголовке этого вопроса.

Мои требованиябыли в основном:

1) Если в шаблоне есть динамические части, они должны быть в состоянии визуализировать себя индивидуально - без необходимости повторной визуализации всего шаблона с обновленными данными.

2) Динамические части не нужно разбивать на свои собственные шаблоны на том же уровне, что и родительский шаблон;скорее, должна быть своего рода иерархия шаблонов - шаблон, объявляющий все необходимые суб-шаблоны для себя.

Концепция вложенных шаблонов в Underscore.js такая же, как в PHP (дляпример).Следующий код является примером «эхо PHP»:

<?php echo '<?php echo $var_unknown_until_runtime; ?>'; ?>

Хотя этот вложенный синтаксис может быть очень запутанным и запутанным, идея проста:

Эхо-код, который будетзначения эха позже.

Это относится и к шаблонам Underscore.js.


Пример

Код будет выглядеть следующим образом:

<script type="text/template" id="outer-tpl">
    <%= value %>

    <script type="text/template" id="inner-tpl">
        <%= '<%= value %\>' %> <!-- NOTE how the inner '>' is escaped ('\>') -->
    <%= "</script\>" %> <!-- NOTE same thing -->
</script>

Давайте немного разберемся с этим.Строка с первым NOTE является нашей ключевой строкой здесь.Обычно, когда Underscore компилирует этот шаблон, можно ожидать, что значение value будет напечатано как во внешнем, так и во внутреннем шаблонах.Чтобы предотвратить это, мы сделали несколько вещей:

1) Превратим вложенный оператор подчеркивания в строку.

2) Интерполируем эту строку (<%= "string here" %>).

3) Избегать закрывающего > во вложенном выражении подчеркивания (\>).Это не позволяет регулярному выражению Underscore сопоставить это с открывающим тегом из шага 2 (<%=).Когда эта строка повторяется, escape-символ будет удален, и %> будет готов для интерпретации Underscore на следующем проходе.

То же самое происходит во втором NOTE в нашемПример не позволяет браузеру завершить первый тег script.Вложенные теги script технически не допускаются, поэтому браузер ищет первую последовательность символов: </script> и затем завершает выполнение скрипта.Это останавливает браузер от распознавания этой последовательности.

Более подробный пример см. В этом JSFiddle .


Отказ от ответственности

Я не одобряю это как лучший способ сделать что-то подобное.В конце концов, это очень хакерский.Хотя ответ @John z нарушает мое первое требование, которое для меня было неприемлемым, другой вариант разделения динамических частей шаблона на их собственные шаблоны может оказаться более простым.Это просто менее организовано.

Расположение всех этих вложенных тегов script в вашей DOM может быть трудно отследить (так как вложенные теги script будут динамически внедряться в DOM, когда и где бы вы ни находилисьвставить внешний шаблон).Риск дублирования высок и может быть раздражающим в обслуживании.

Сложность вложения шаблонов резко возрастает для каждого уровня вложения (чтобы вложить шаблон во вложенный шаблон, вам придется снова избегать всего, так далее...).Скрипка включает пример этого.

...