Лучшая практика для хранения HTML-шаблонов на странице?

Я разрабатываю довольно тяжелый интерфейс JavaScript для сайта, который я создаю, и я решил использовать (недавно сделанный официальным) плагин шаблонов jQuery для создания моих элементов из моих запросов к JSON API. Теперь проблема, с которой я сейчас сталкиваюсь:

Я склонен иметь кучу этих шаблонов вокруг. По одному для каждого типа объектов, некоторые для списков, некоторые для разделов страницы и т. д. Есть ли предпочтительный способ хранения этих шаблонов? Я читал об определении тега <script> с помощью id с использованием имени шаблона, а затем извлечения оттуда текста (как описывает Джон Резиг в "JavaScript Micro-Templating"), но наличие множества этих тегов <script> на каждой отдельной странице выглядит немного хакерским.

Итак, вопрос: есть ли какая-либо «лучшая практика» для такого сценария?


person dguaraglia    schedule 18.11.2010    source источник
comment
Является ли метод этого <script> не позволяющим браузеру даже анализировать html в теге?   -  person Webnet    schedule 19.11.2010
comment
@Webnet идея состоит в том, что вы устанавливаете тип text/html, и, поскольку браузер не знает, что с этим делать, он просто игнорирует содержимое тега script.   -  person dguaraglia    schedule 19.11.2010


Ответы (6)


Почему бы просто не загрузить свои шаблоны в скрытый элемент, а затем использовать $(template).clone()? Это избавляет от многих головных болей. Я не могу говорить о производительности при подходе .clone() по сравнению с подходом <script>, но могу сказать вам, что дополнительные теги сценария снижают производительность и обычно делают код грязным.

Почему?

  • Даже если у вас есть шикарная утилита для экранирования, ошибки все равно будут допущены, и их будет намного сложнее прочитать. Кроме того, если вам приходится работать в команде, особенно если люди включаются/выключаются из проекта, это может быть нелегко понять.

  • вы можете создать объект-указатель, скажем, templates = {}, и загрузить его указателями объектов jquery на ваши клонируемые элементы, например:

     templates = {};
     templates.message = $("#templates .message");
     templates.dialog = $("#templates .dialog");
    

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

var newDialog = templates.dialog.clone();

Вы можете создать функцию-оболочку для приема параметров, а затем добавить их с помощью newDialog.find("title").html(title), newDialog.find("message").html(message), и т. д.

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

Другим важным аспектом производительности является синхронизация... если вы испытываете задержки производительности, вы должны убедиться, что разбиваете свои куски длинного исполняемого кода с помощью setTimeout. Он создает новый стек и позволяет браузеру рисовать то, что он уже обработал до момента непосредственно перед созданием нового стека. Это очень помогает при работе с визуальными задержками как частью проблемы с производительностью (как правило, это наиболее распространенная проблема с производительностью, особенно среди тех, кто не занимается кодированием). Если вам нужна дополнительная информация об этом, отправьте мне сообщение, и я соберу некоторые ресурсы. Сейчас ограниченное время, тушение пожаров на работе. :)

person Jess Jacobs    schedule 22.11.2010
comment
Назначение шаблона — легко вставлять в него данные. Клонирование DocumentFragment сделало бы этот процесс чрезвычайно болезненным. Я могу сгенерировать html из шаблона в одну строку кода. - person Adam Lassek; 23.11.2010
comment
.clone() — это глубокий метод; как будет больно? - person Jess Jacobs; 29.03.2011
comment
как бы вы вставляли данные в разметку, не делая это по одному элементу за раз? - person Adam Lassek; 29.03.2011
comment
сравните ваш пример выше с Mustache.to_html(templates.dialog, { title: title, message: message }) - person Adam Lassek; 29.03.2011
comment
При таком подходе вы больше не можете использовать id-атрибуты. Они не уникальны после клонирования. - person user414873; 18.01.2014
comment
этот вопрос должен быть закрыт, потому что он не имеет значения сейчас, когда существует 10 миллионов решений для шаблонов. Даже моему ответу 3,5 года. - person Jess Jacobs; 25.03.2014
comment
Это не только нарушает id-атрибуты, как указано выше, но также существует риск того, что скрипты увидят содержимое скрытого элемента как часть DOM и будут работать с ним. Не говоря уже о том, что поисковые системы наказывают ваш сайт за сокрытие контента от пользователя. - person Lex; 16.03.2016
comment
Смотрите мой ответ выше. Это мега старо. Клонирование — ужасный способ создания новых узлов сейчас, когда доступны более производительные решения. - person Jess Jacobs; 17.03.2016
comment
Кроме того, использование идентификатора в шаблоне в любом случае является плохой идеей по понятным причинам... поэтому нарушение идентификаторов не является серьезной проблемой, когда речь идет о шаблонах. Mustache, Underscore и любые более крупные фреймворки (я предпочитаю React) миллион раз решали эту проблему. Пожалуйста, не обращайте внимания на мой первоначальный ответ выше. Говоря об этом, действительно должен быть способ избавить stackoverflow от устаревших статей вопросов/ответов. Здесь? - person Jess Jacobs; 17.03.2016

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

Моя версия представляет собой базовый шаблон и замену с использованием заменяемых значений в form ##VALUE##

ШАБЛОН: (шаблон отдельного элемента или шаблон строки)

<script type="text/html" id="ItemTemplate">
<table>
  <tr>
    <td>##LABEL1##</td>
    <td>##VALUE1##</td>
  <tr>
</table>
</script>

ФУНКЦИЯ СОЗДАНИЯ КОНТЕНТА:

function constructFromTemplate(content, values, appendTo) {
    var modifiedHtml = content;
    modifiedHtml = modifiedHtml.replace(new RegExp('__', 'g'), '##');

    $.each(values, function (n, v) {
        modifiedHtml = modifiedHtml.replace(new RegExp('##' + n + '##', 'g'), v);
    });

    if (appendTo != null) 
    {
        $(appendTo).append(modifiedHtml);
        //initializePageElements();
    }

    return modifiedHtml;
}

ИСПОЛЬЗОВАНИЕ

Содержимое будет возвращено из функции, и/или вы можете установить параметр appendTo, установив elementID для автоматического append содержимого. (установите null вместо append)

Заменяемые значения просто добавляются как динамический объект, где object имен являются заменяемыми элементами.

var theContent = constructFromTemplate(ItemTemplate, { LABEL1: 'The Label 1 content', LABEL2: 'The Label 2 content' }, null);

Примечание: я закомментировал //initializePageElements();, это используется для инициализации jQuery плагинов и стилей в шаблоне.

Кажется, что при вставке содержимого в DOM работают только встроенные стили.

person Mark Redman    schedule 18.11.2010
comment
Просто из любопытства: что это за подход? :) - person dguaraglia; 19.11.2010

посмотрите на https://github.com/inspiraller/STQuery.

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

var strTemplate = '<div id="splog"><h1>lorem ipsum</h1><div class="content">lorem ipsum</div></div>';

var ST = STQuery(strTemplate);

ST.find('h1').html('Hello');
ST.find('.content').html('World!');

var strTemplateUpdated = ST.html();

Это отделяет логику от шаблона, т.е. ненавязчивые HTML-шаблоны.

Преимущество по сравнению с jquery заключается в том, что STQuery не нужно сначала записывать в DOM, что означает, что вы можете использовать веб-воркеры или выполнять все манипуляции с шаблонами на сервере. Примечание: начиная с этого сообщения, stquery был написан только на javascript, поэтому его необходимо преобразовать в выбранный язык на стороне сервера.

person steve    schedule 20.07.2011

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

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

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

Я, конечно, хотел бы услышать, как другие решили эту проблему.

person Adam Lassek    schedule 18.11.2010
comment
Я согласен с тем, что идеальным сценарием является то, что шаблоны уже являются частью веб-страницы. Одна вещь, которую я изучаю, это, возможно, использовать только one тег скрипта для загрузки всех шаблонов вместо того, чтобы иметь один тег для каждого шаблона. Еще одна оптимизация, о которой я думаю, заключается в том, чтобы скрипт Python объединил все шаблоны в файл .js и минимизировал его. Это, вероятно, оптимальный способ сделать это, но это сделает разработку занозой в заднице. - person dguaraglia; 19.11.2010
comment
@dguaraglia Однако у того, о чем вы говорите, есть пара недостатков. Если вы хотите объединить все шаблоны в один раздел скрипта, то вам нужно закодировать их для javascript и записать каждый в переменную или что-то еще, что будет выглядеть еще уродливее. Если вы не думаете о том, чтобы обернуть их в родительский контейнер, в этом случае я не вижу преимущества перед несколькими тегами script. - person Adam Lassek; 20.11.2010
comment
@dguaraglia Вы также не можете минимизировать HTML. Это только сделает его более уродливым, но вы не сэкономите много места. Лучше держать его читабельным, ИМО. - person Adam Lassek; 20.11.2010
comment
На самом деле, с тех пор я обнаружил, что существуют инструменты, такие как Jammit, которые преобразуют шаблоны в правильные экранированные строки JavaScript, оборачивает их в функцию, которая вызывает средство визуализации и помещает их в пространство имен. Я пытаюсь расширить Django-Assets, чтобы сделать то же самое. - person dguaraglia; 20.11.2010
comment
@dguaraglia Вау, Джаммит выглядит потрясающе. Спасибо за внимание. - person Adam Lassek; 20.11.2010

Я успешно использовал скрипт с моим фреймворком jquery pure html templates

Что касается лучших практик, обратите внимание на новый интерфейс Twitter, использующий одну страницу для всего и только внутреннюю маршрутизацию через "#!/paths".

Использование швов одностраничных веб-сайтов станет следующим большим шагом для веб-приложений, лично мне нравится называть это web 3.0 :) Это также устранит проблему наличия одинаковых шаблонов на каждой странице — у вас будет только одна страница.

person mpapis    schedule 19.11.2010

В asp.net mvc я часто упаковываю свои общие шаблоны в частичное представление, которое я могу включить там, где мне это нужно. Таким образом, мне не нужно повторять мои шаблоны повсюду.

Другой подход — хранить ваши шаблоны в отдельных файлах. Например, newslist.tmpl.html, который позволяет загружать шаблон с помощью ajax. Учитывая, что это можно сделать параллельно с загрузкой данных, это не должно замедлять работу вашего приложения, поскольку в любом случае это, скорее всего, быстрее, чем вызов данных.

person Mikael Eliasson    schedule 22.11.2010