Недавно я столкнулся с усами, которые, как утверждается, являются шаблоном без логики .
Однако нет объяснения, почему он разработан без логики. Другими словами, в чем преимущество шаблона без логики?
Недавно я столкнулся с усами, которые, как утверждается, являются шаблоном без логики .
Однако нет объяснения, почему он разработан без логики. Другими словами, в чем преимущество шаблона без логики?
Ответы:
Другими словами, это не дает вам выстрелить себе в ногу. В старые времена JSP было очень распространено, чтобы файлы JSP были присыпаны кодом Java, что значительно усложняло рефакторинг, поскольку у вас был разбросанный код.
Если вы предотвращаете логику в шаблонах по дизайну (как это делают усы), вы будете обязаны разместить логику в другом месте, так что ваши шаблоны останутся незагроможденными.
Еще одно преимущество состоит в том, что вы вынуждены мыслить в терминах разделения проблем: ваш контроллер или логический код должны будут выполнять массирование данных перед отправкой данных в пользовательский интерфейс. Если позже вы переключите свой шаблон на другой (скажем, вы начнете использовать другой механизм шаблонов), переход будет простым, потому что вам нужно было только реализовать детали пользовательского интерфейса (помните, что в шаблоне нет логики).
У меня такое ощущение, что я почти одинок на мой взгляд, но я твердо нахожусь в противоположном лагере. Я не верю, что возможное смешение бизнес-логики в ваших шаблонах является достаточной причиной не использовать всю мощь вашего языка программирования.
Обычный аргумент в пользу шаблонов без логики состоит в том, что если у вас есть полный доступ к вашему языку программирования, вы можете смешать логику, которой нет места в шаблоне. Я считаю, что это похоже на рассуждение о том, что вы должны использовать ложку, чтобы нарезать мясо, потому что вы можете порезаться, используя нож. Это очень верно, и все же вы будете гораздо более продуктивны, если будете использовать последнее, хотя и осторожно.
Например, рассмотрим следующий фрагмент шаблона с использованием усов :
{{name}}:
<ul>
{{#items}}
<li>{{.}}</li>
{{/items}}
</ul>
Я могу это понять, но считаю следующее (с использованием подчеркивания ) более простым и понятным :
<%- name %>:
<ul>
<% _.each(items, function(i){ %>
<li><%- i %></li>
<% }); %>
</ul>
При этом я понимаю, что шаблоны без логики имеют преимущества (например, они могут использоваться с несколькими языками программирования без изменений). Я думаю, что эти другие преимущества очень важны. Я просто не думаю, что их бессмысленная природа - одна из них.
name
и items
мог содержать JavaScript.
Усы лишены логики?
Разве это не так:
{{#x}}
foo
{{/x}}
{{^x}}
bar
{{/x}}
Довольно похоже на это?
if x
"foo"
else
"bar"
end
И разве это не похоже на логику представления (читай: почти на определение)?
if x > 0 && x < 10
) ... Итак, хотя можно использовать Mustache с логикой или без нее, решать вам. В конце концов, это всего лишь инструмент.
Шаблон без логики - это шаблон, который содержит дыры, которые вы должны заполнить, а не то, как вы их заполняете. Логика размещается в другом месте и отображается непосредственно в шаблоне. Такое разделение задач идеально, потому что тогда шаблон можно легко построить с другой логикой или даже с другим языком программирования.
Из руководства по усам :
Мы называем это «без логики», потому что здесь нет операторов if, предложений else или циклов for. Вместо этого есть только теги. Некоторые теги заменяются значением, некоторые - ничем, а другие - серией значений. В этом документе объясняются различные типы тегов усов.
Обратной стороной медали является то, что в отчаянной попытке убрать бизнес-логику из презентации вы в конечном итоге добавляете в модель много логики презентации. Типичным примером может быть то, что вы хотите поместить «нечетные» и «четные» классы в чередующиеся строки в таблице, что можно сделать с помощью простого оператора по модулю в шаблоне представления. Но если ваш шаблон представления не позволяет вам это сделать, тогда в данных вашей модели вы должны не только сохранить, какая строка является нечетной или четной, но в зависимости от того, насколько ограничен ваш механизм шаблонов, вам может даже потребоваться загрязнить вашу модель. с именами реальных классов CSS. Представления должны быть отделены от моделей, точка. Но модели также должны быть независимыми от представлений, и именно об этом заставляют забыть многие из этих «не логических» шаблонизаторов. Логика идет в обоих местах,собственно, чтобы правильно решить, куда он идет. Это проблема презентации или проблема бизнеса / данных? Чтобы иметь 100% первозданный вид, загрязнение попадает в другое менее заметное, но столь же неподходящее место.
Наблюдается растущее движение в обратном направлении, и, надеюсь, все будет сосредоточено где-то на более разумной золотой середине.
Это делает ваши шаблоны более чистыми и заставляет вас хранить логику в том месте, где ее можно должным образом протестировать.
Этот разговор похож на то, когда средневековые монахи спорили о том, сколько ангелов может поместиться на конце булавки. Другими словами, он начинает чувствовать себя религиозным, бесполезным и неправильно сфокусированным.
Далее следует мини-разглагольствование (не обращайте внимания):
Если вы не хотите продолжать читать ... Мой короткий ответ на вышеупомянутую тему: я не согласен с шаблонами без логики. Я считаю это программной формой экстремизма. :-) :-)
Теперь моя напыщенная речь идет полным ходом: :-)
Я думаю, если довести многие идеи до крайности, результат станет смехотворным. И иногда (то есть в этой теме) проблема заключается в том, что мы доводим «неправильную» идею до крайности.
Убирать всю логику из представления - «нелепо» и неправильная идея.
Отступите на мгновение.
Нам нужно задать себе вопрос: зачем убирать логику? Концепция, очевидно, заключается в разделении интересов . Держите обработку представления как можно более отдельной от бизнес-логики. Зачем это делать? Это позволяет нам поменять местами представления (для разных платформ: мобильные, браузерные, настольные и т. Д.), И это позволяет нам более легко поменять местами поток управления, последовательность страниц, изменения проверки, изменения модели, доступ безопасности и т. Д. Также, когда логика удаленный из представлений (особенно веб-представлений), он делает представления более читаемыми и, следовательно, более удобными в обслуживании. Я понимаю и согласен с этим.
Однако первоочередное внимание следует уделять разделению интересов. Не представления, на 100% лишенные логики. Логика внутри представлений должна относиться к тому, как визуализировать «модель». Насколько я понимаю, логика представлений в порядке. У вас может быть логика представления, которая не является бизнес-логикой.
Да, в те времена, когда мы писали JSP, PHP или ASP-страницы с минимальным разделением логики кода и логики представления или совсем без него, обслуживание этих веб-приложений было абсолютным кошмаром. Поверьте, я знаю, что я создал и поддерживал некоторые из этих чудовищ. Именно на этом этапе обслуживания я действительно осознал (внутренне) ошибку своего пути и пути моих коллег. :-) :-)
Итак, указ сверху (отраслевые эксперты) стал: вы должны структурировать свои веб-приложения, используя что-то вроде контроллера переднего вида (который отправляется обработчикам или действиям [выберите свою веб-структуру]), и ваши представления не должны содержать кода . Представления должны были стать тупыми шаблонами.
Таким образом, я в целом согласен с вышеизложенным мнением, но не в отношении специфики пунктов указа, а, скорее, в отношении мотивации указа, которая заключается в стремлении разделить проблемы между представлением и бизнес-логикой.
В одном проекте, в котором я принимал участие, мы пытались довести идею бессмысленного взгляда до смехотворной крайности. У нас был собственный шаблонизатор, который позволял нам отображать объекты модели в html. Это была простая система на основе токенов. Это было ужасно по одной очень простой причине. Иногда в представлении нам приходилось решать, следует ли мне отображать этот небольшой фрагмент HTML ... или нет ... Решение обычно основывается на некотором значении в модели. Когда у вас нет абсолютно никакой логики в представлении, как вы это делаете? Вы не можете. У меня были серьезные споры с нашим архитектором по этому поводу. Люди, занимающиеся интерфейсом HTML, пишущие наши представления, были полностью расстроены, когда столкнулись с этим, и были очень напряжены, потому что не могли достичь своих простых целей. Поэтому я представил концепцию простого IF-оператора в нашем движке шаблонов. Я не могу описать вам наступившее облегчение и спокойствие. Проблема была решена с помощью простой концепции IF-Statement в наших шаблонах! Внезапно наш шаблонизатор стал хорошим.
Так как же мы попали в эту глупую стрессовую ситуацию? Мы сфокусировались не на той цели. Мы следовали правилу, вы не должны иметь никакой логики в своих взглядах. Это было неправильно. Я думаю, что "практическое правило" должно сводить к минимуму количество логики в ваших представлениях. Потому что, если вы этого не сделаете, вы можете непреднамеренно позволить бизнес-логике проникнуть в представление, что нарушает разделение функций.
Я понимаю, что когда вы заявляете, что «у вас не должно быть логики в представлениях», становится легко узнать, когда вы являетесь «хорошим» программистом. (Если это ваша мера доброты). Теперь попробуйте реализовать веб-приложение даже средней сложности с указанным выше правилом. Это не так-то просто сделать.
Для меня правило логики во взглядах не так однозначно, и, честно говоря, я хочу, чтобы оно было именно таким.
Когда я вижу много логики в представлениях, я улавливаю запах кода и пытаюсь устранить большую часть логики из представлений - я стараюсь, чтобы бизнес-логика существовала где-то еще - я пытаюсь разделить проблемы. Но когда я начинаю болтать с людьми, которые говорят, что мы должны убрать всю логику из поля зрения, ну, для меня это просто попахивает фанатизмом, поскольку я знаю, что вы можете попасть в ситуации, подобные описанным выше.
Я закончил свою тираду. :-)
Привет,
Дэвид
Лучший аргумент, который я придумал для шаблонов без логики, - это то, что вы можете использовать одни и те же шаблоны как на клиенте, так и на сервере. Однако на самом деле вам не нужен бессмысленный, просто тот, у которого есть свой «язык». Я согласен с людьми, которые жалуются, что усы бессмысленно ограничивают. Спасибо, но я большой мальчик и могу содержать свои шаблоны в чистоте без вашей помощи.
Другой вариант - просто найти синтаксис шаблонов, который использует язык, поддерживаемый как клиентом, так и сервером, а именно javascript на сервере, либо с помощью node.js, либо вы можете использовать интерпретатор js и json через что-то вроде therubyracer.
Затем вы можете использовать что-то вроде haml.js, которое намного чище, чем любой из приведенных до сих пор примеров, и отлично работает.
Одним предложением: отсутствие логики означает, что сам шаблонизатор менее сложен и, следовательно, занимает меньше места, и у него меньше возможностей для неожиданного поведения.
Несмотря на то, что вопрос старый и на него дан ответ, я хотел бы добавить свои 2 ¢ (что может звучать как напыщенная речь, но это не так, речь идет об ограничениях и о том, когда они становятся неприемлемыми).
Цель шаблона - отрисовать что-то, а не выполнять бизнес-логику. Теперь есть тонкая грань между невозможностью делать то, что вам нужно сделать в шаблоне, и наличием в них «бизнес-логики». Несмотря на то, что я был очень позитивно настроен по отношению к Moustache и пытался использовать его, в конце концов я не мог делать то, что мне нужно, в довольно простых случаях.
«Массование» данных (если использовать слова в принятом ответе) может стать настоящей проблемой - не поддерживаются даже простые пути (то, что адресовано Handlebars.js). Если у меня есть данные просмотра, и мне нужно настраивать их каждый раз, когда я хочу что-то отрендерить, потому что мой шаблонизатор слишком ограничивает, тогда это в конечном итоге не поможет. И это побеждает часть платформенной независимости, которую усы заявляют сами; Я должен везде дублировать логику массажа.
Тем не менее, после некоторого разочарования и после опробования других шаблонизаторов мы закончили тем, что создали наш собственный (... еще один ...), который использует синтаксис, вдохновленный шаблонами .NET Razor. Он анализируется и компилируется на сервере и генерирует простую автономную JS-функцию (фактически как модуль RequireJS), которую можно вызвать для «выполнения» шаблона, возвращая в качестве результата строку. Образец, приведенный Брэдом, будет выглядеть следующим образом при использовании нашего движка (который я лично считаю намного лучше, чем Mustache и Underscore):
@name:
<ul>
@for (items) {
<li>@.</li>
}
</ul>
Еще одно ограничение, лишенное логики, поразило нас при вызове частичных файлов с помощью Mustache. Хотя частичные данные поддерживаются в Mustache, нет возможности настроить данные, которые будут передаваться первыми. Поэтому вместо того, чтобы иметь возможность создавать модульный шаблон и повторно использовать небольшие блоки, я в конечном итоге буду создавать шаблоны с повторяющимся кодом в них.
Мы решили это, реализовав язык запросов, вдохновленный XPath, который мы назвали JPath. По сути, вместо использования / для перехода к дочерним элементам мы используем точки, и поддерживаются не только строковые, числовые и логические литералы, но также объекты и массивы (как JSON). Язык не имеет побочных эффектов (что является обязательным условием для создания шаблонов), но позволяет «массировать» данные по мере необходимости путем создания новых буквальных объектов.
Допустим, мы хотим визуализировать таблицу «сетки данных» с настраиваемыми заголовками и ссылками на действия в строках, а затем динамически добавлять строки с помощью jQuery. Поэтому строки должны быть частичными, если я не хочу дублировать код. И здесь начинается проблема, если некоторая дополнительная информация, например, какие столбцы должны отображаться, является частью модели представления, и то же самое для этих действий в каждой строке. Вот фактический рабочий код с использованием нашего шаблона и механизма запросов:
Шаблон таблицы:
<table>
<thead>
<tr>
@for (columns) {
<th>@title</th>
}
@if (actions) {
<th>Actions</th>
}
</tr>
</thead>
<tbody>
@for (rows) {
@partial Row({ row: ., actions: $.actions, columns: $.columns })
}
</tbody>
</table>
Шаблон строки:
<tr id="@(row.id)">
@for (var $col in columns) {
<td>@row.*[name()=$col.property]</td>
}
@if (actions) {
<td>
@for (actions) {
<button class="btn @(id)" value="@(id)">@(name)...</button>
}
</td>
}
</tr>
Вызов из JS-кода:
var html = table({
columns: [
{ title: "Username", property: "username" },
{ title: "E-Mail", property: "email" }
],
actions: [
{ id: "delete", name: "Delete" }
],
rows: GetAjaxRows()
})
В нем нет бизнес-логики, но он может быть повторно использован и настроен, а также не имеет побочных эффектов.
row
объекта, вместо использования статических имен. Например, если $col.property == 'Something'
тогда это приведет к содержимому row.Something
.
Вот 3 способа отрисовки списка с подсчетом символов. Все, кроме первого и самого короткого, написаны на языках шаблонов без логики.
CoffeeScript (с Reactive Coffee Builder DSL) - 37 символов
"#{name}"
ul items.map (i) ->
li i
Нокаут - 100 символов
<span data-bind="value: name"/>
<ul data-bind="foreach: items">
<li data-bind="value: i"/>
</ul>
Руль / усы - 66 символов
{{name}}:
<ul>
{{#items}}
<li>{{.}}</li>
{{/items}}
</ul>
Подчеркивание - 87 символов
<%- name %>:
<ul>
<% _.each(items, function(i){ %>
<li><%- i %></li>
<% }); %>
</ul>
Я полагаю, что обещание шаблонов без логики заключалось в том, что люди с более широким набором навыков смогут управлять шаблонами без логики, не стреляя себе в ногу. Однако в приведенных выше примерах вы видите, что когда вы добавляете язык с минимальной логикой к разметке на основе строк, результат получается более сложным, а не менее. Кроме того, вы выглядите так, будто используете PHP старой школы.
Ясно, что я не возражаю против исключения «бизнес-логики» (обширных вычислений) в шаблонах. Но я думаю, что за предоставление им псевдоязыка для логики отображения вместо первоклассного языка приходится платить. Не просто больше набирать, а отвратительное сочетание переключения контекста, которое кому-то нужно прочитать.
В заключение, я не вижу логики шаблонов без логики, поэтому я бы сказал, что их преимущества для меня нулевые, но я уважаю, что многие в сообществе видят это по-другому :)
Основные преимущества использования шаблонов без логики:
Я согласен с Брэдом: underscore
стиль легче понять. Но я должен признать, что синтаксический сахар может понравиться не всем. Если _.each
это несколько сбивает с толку, вы можете использовать традиционный for
цикл.
<% for(var i = 0; i < items.length; i++) { %>
<%= items[i] %>
<% } %>
Всегда хорошо, если вы можете вернуться к стандартным конструкциям, таким как for
или if
. Просто используйте <% if() %>
или в <% for() %>
то время как Mustache
используйте неологизм для if-then-else
(и сбивает с толку, если вы не читали документацию):
{{#x}}
foo
{{/x}}
{{^x}}
bar
{{/x}}
Движок шаблонов хорош, когда вы можете легко создавать вложенные шаблоны ( underscore
стиль):
<script id="items-tmpl" type="text/template">
<ul>
<% for(var i = 0; i < obj.items.length; i++) { %>
<%= innerTmpl(obj.items[i]) %>
<% } %>
</ul>
</script>
<script id="item-tmpl" type="text/template">
<li>
<%= name %>
</li>
</script>
var tmplFn = function(outerTmpl, innerTmpl) {
return function(obj) {
return outerTmpl({obj: obj, innerTmpl: innerTmpl});
};
};
var tmpl = tmplFn($('#items-tmpl').html(), $('#item-tmpl').html());
var context = { items: [{name:'A',{name:'B'}}] };
tmpl(context);
В основном вы передаете свой внутренний tmpl как свойство вашего контекста. И назовите это соответственно. Сладкий :)
Кстати, если единственное, что вас интересует, это механизм шаблонов, используйте автономную реализацию шаблона. При минификации это всего 900 символов (4 длинные строки):