Нещодавно я зіткнувся з вусами, які, як стверджується, є шаблоном без логіки .
Однак немає пояснень, чому це розроблено без логіки. Іншим словом, яка перевага шаблону без логіки?
Нещодавно я зіткнувся з вусами, які, як стверджується, є шаблоном без логіки .
Однак немає пояснень, чому це розроблено без логіки. Іншим словом, яка перевага шаблону без логіки?
Відповіді:
Іншими словами, це заважає вам стріляти в ногу. У старі часи JSP дуже часто зустрічалися JSP-файли, посипані кодом Java, що зробило рефакторинг набагато складніше, оскільки у вас був розсіяний ваш код.
Якщо ви заважаєте логіці в шаблонах за допомогою дизайну (як це роблять вуса), ви будете зобов'язані розмістити цю логіку в іншому місці, щоб ваші шаблони в кінцевому підсумку були розбиті.
Ще одна перевага полягає в тому, що ви змушені думати над розділенням проблем: ваш контролер або логічний код доведеться робити масаж даних, перш ніж надсилати дані в інтерфейс користувача. Якщо пізніше ви переключите ваш шаблон на інший (скажімо, ви почнете використовувати інший движок шаблонів), перехід буде легким, оскільки вам довелося реалізувати лише дані інтерфейсу користувача (оскільки в шаблоні немає логіки, пам’ятайте).
У мене виникає відчуття, що я майже один на мою думку, але я твердо перебуваю в протилежному таборі. Я не вірю, що можливе змішування ділової логіки у ваших шаблонах є достатньою причиною не використовувати всю потужність вашої мови програмування.
Звичайний аргумент для шаблонів без логіки полягає в тому, що якщо у вас є повний доступ до вашої мови програмування, ви можете змішатися в логіці, яка не має місця в шаблоні. Я вважаю це схожим на міркування, що ви повинні використовувати ложку для скибочки м'яса, тому що ви могли порізати себе, якщо використовуєте ніж. Це дуже вірно, і все ж ви будете набагато продуктивнішими, якщо будете користуватися останнім, хоча і обережно.
Наприклад, розгляньте такий фрагмент шаблону за допомогою вусів :
{{name}}:
<ul>
{{#items}}
<li>{{.}}</li>
{{/items}}
</ul>
Я можу це зрозуміти, але я вважаю, що наступне (за допомогою підкреслення ) набагато простіше і прямо:
<%- name %>:
<ul>
<% _.each(items, function(i){ %>
<li><%- i %></li>
<% }); %>
</ul>
Зважаючи на це, я розумію, що шаблони logicless мають переваги (наприклад, вони можуть використовуватися з різними мовами програмування без змін). Я думаю, що ці інші переваги дуже важливі. Я просто не думаю, що їхня менш логічна природа є однією з них.
name
і items
може містити JavaScript.
Вуса без логіки?
Чи не це:
{{#x}}
foo
{{/x}}
{{^x}}
bar
{{/x}}
Досить схожий на це?
if x
"foo"
else
"bar"
end
І це не що дуже схоже на (читай: майже) визначення логіки уявлення?
if x > 0 && x < 10
) ... Отже, поки можна використовувати вуса з логікою або без неї, це залежить від вас. Адже це просто інструмент.
Шаблон без логіки - це шаблон, який містить отвори, які ви повинні заповнити, а не те, як ви їх заповнюєте. Логіка розміщується в іншому місці і відображається безпосередньо до шаблону. Таке розмежування проблем ідеально, тому що тоді шаблон може бути легко побудований з різною логікою або навіть з іншою мовою програмування.
Ми називаємо це "менш логічним", тому що немає, якщо заяви, інші пункти чи цикли. Натомість є лише теги. Деякі теги замінюються значенням, деякі нічим, а інші рядом значень. Цей документ пояснює різні типи вусів.
Зворотний бік монети полягає в тому, що у відчайдушній спробі утримати ділову логіку від презентації ви в кінцевому підсумку вкладаєте багато логіки презентації в модель. Загальним прикладом може бути те, що ви хочете помістити класи "непарні" та "парні" на чергування рядків у таблиці, що можна зробити за допомогою простого оператора модуля в шаблоні подання. Але якщо шаблон вашого перегляду не дозволяє вам це робити, то в даних вашої моделі ви повинні не тільки зберігати, чий рядок є непарним або парним, але залежно від того, наскільки обмежена система вашого шаблону, вам може знадобитися навіть забруднити вашу модель. з назвами фактичних класів CSS. Перегляди повинні бути окремими від Моделей, повної зупинки. Але Моделі також повинні бути агностическими, і саме те багато хто з цих двигунів шаблонів "без логіки" змушують вас забути. Логіка йде в обох місцях,насправді правильно вирішити, куди йде. Це стурбованість презентації чи проблема бізнесу / даних? Прагнучи мати 100% незайманий вид, забруднення просто потрапляє в інше менш видиме, але не менш підходяще місце.
Зростаючий рух назад в інший бік, і, сподіваємось, все буде десь зосереджено на більш розумному середині.
Це робить ваші шаблони більш чистими, і змушує вас зберігати логіку там, де його можна правильно перевірити.
Ця розмова виглядає так, коли ченці середніх віків дискутували б про те, скільки ангелів може поміститися на кінці шпильки. Іншими словами, вона починає відчувати себе релігійною, марною і неправильно зосередженою.
Міні-рейнт випливає (не соромтесь ігнорувати):
Якщо ви не хочете продовжувати читати. Моя коротка відповідь на вищевказану тему: я не згоден із шаблонами, що не мають логіки. Я вважаю це формою програмування екстремізму. :-) :-)
Тепер мій розмах продовжується повним ходом: :-)
Я думаю, що коли ти доводиш багато ідей до кінця, результат стає смішним. І іноді (тобто ця тема) питання полягає в тому, що ми сприймаємо "неправильну" ідею до кінця.
Видалення всієї логіки з виду - це "глузлива" і неправильна ідея.
На мить відступимо.
Питання, яке ми мусимо задати собі, це навіщо знімати логіку? Концепція, очевидно, є розділенням проблем . Тримайте обробку перегляду максимально відокремленою від бізнес-логіки. Навіщо це робити? Це дозволяє нам обмінятись переглядами (для різних платформ: мобільних, браузерів, настільних пристроїв тощо), і дозволяє нам легше поміняти потоки управління, послідовність сторінок, зміни валідації, зміни моделі, доступ до безпеки тощо. Також, коли логіка є вилучений із представлень даних (особливо веб-переглядів), це робить перегляди набагато зручнішими для читання та, отже, більш ремонтованими. Я це розумію і з цим згоден.
Однак головна увага повинна бути зосереджена на розділенні проблем. Не 100% без логіки переглядів. Логіка в поглядах повинна стосуватися способу візуалізації "моделі". Що стосується мене, то логіка в поглядах ідеально чудова. Ви можете мати логіку перегляду, яка не є бізнес-логікою.
Так, ще в той час, коли ми писали сторінки JSP, PHP або ASP з невеликим або відсутнім розділенням логіки коду та логіки перегляду, підтримка цих веб-додатків була абсолютним кошмаром. Повірте, я знаю, я створив і потім підтримував деякі з цих жахливих явищ. Саме під час того етапу технічного обслуговування я дійсно зрозумів (візуально) помилку моїх та моїх колег. :-) :-)
Таким чином, едікт з високого рівня (галузевий експерт) став, ви повинні структурувати свої веб-додатки, використовуючи щось на кшталт контролера перегляду спереду (який надсилається до обробників або дій [виберіть веб-каркас]), і ваші погляди не повинні містити код . Погляди мали стати тупими шаблонами.
Тож я погоджуюсь загалом з вищенаведеними настроями не щодо специфіки пунктів едикту, а скоріше мотивації, що стоїть за едіктом, - що є прагненням до розмежування проблем між поглядом та діловою логікою.
В одному з проектів, в якому я брав участь, ми намагалися дотримуватися ідеї, що не сприймає логіку, до глузливої крайності. У нас був домашній шаблон двигуна, який би дозволяв нам відображати об'єкти моделі в html. Це була проста система на основі лексеми. Це було жахливо з однієї дуже простої причини. Іноді, з точки зору, нам доводилося вирішувати, чи слід відображати цей невеликий фрагмент HTML .. чи ні. Рішення зазвичай базується на деякому значенні в моделі. Коли у вас абсолютно немає логіки в погляді, як це зробити? Ну ти не можеш. Я мав кілька основних аргументів з нашим архітектором з цього приводу. Люди, які пишуть наші погляди, були повністю перешкоджені, коли стикалися з цим, і були дуже підкреслені, оскільки не могли досягти своїх інакше простих цілей. Тому я представив концепцію простого IF-твердження в нашому шаблоні. Я не можу описати вам полегшення та спокій, що настали. Проблема була вирішена за допомогою простої концепції IF-Statement у наших шаблонах! Раптом наш шаблонний двигун став хорошим.
То як ми потрапили в цю дурну стресову ситуацію? Ми зосередилися на неправильній цілі. Ми дотримувались правила, ви не повинні мати жодної логіки у своїх поглядах. Це було неправильно. Я думаю, що "правилом" слід бути, мінімізуйте цю логіку у ваших поглядах. Тому що, якщо ви цього не зробите, ви можете ненавмисно дозволити діловій логіці прокрастись у вигляд - це порушує розділення проблем.
Я розумію, що коли ти заявляєш, що "ти не повинен мати логіки у поглядах", стає легко зрозуміти, коли ти "хороший" програміст. (Якщо це міра вашої доброти). Тепер спробуйте реалізувати веб-додаток навіть середньої складності з вищезазначеним правилом. Це не так легко зробити.
Для мене правило логіки у поглядах не настільки чітке вирізання і, відверто кажучи, саме там я хочу.
Коли я бачу багато логіки у поглядах, я виявляю кодовий запах і намагаюся усунути більшу частину логіки з поглядів - я намагаюся забезпечити, щоб бізнес-логіка живе в іншому місці - я намагаюся розділити проблеми. Але коли я починаю спілкуватися з людьми, які кажуть, що ми повинні видалити всю логіку з погляду, ну, мені просто присмакує фанатизм, наскільки я знаю, ти можеш опинитися в таких ситуаціях, як я описав вище.
Я закінчив зі своїм рентом. :-)
Ура,
Девід
Найкращий аргумент, який я придумав для шаблонів logicless, це те, що ви можете використовувати ті самі шаблони як на клієнті, так і на сервері. Однак вам не дуже потрібен logicless, лише той, який має власну "мову". Я погоджуюся з людьми, які скаржаться, що вуса безглуздо обмежують. Дякую, але я великий хлопчик, і я можу зберегти шаблони в чистоті без вашої допомоги.
Інший варіант - просто знайти синтаксис шаблону, який використовує мову, яка підтримується як на клієнті, так і на сервері, а саме javascript на сервері або за допомогою node.js, або ви можете використовувати інтерпретатор js та json через щось на зразок therubyracer.
Тоді ви можете використовувати щось на кшталт haml.js, яке набагато чистіше, ніж будь-який із наведених прикладів, і чудово працює.
В одному реченні: Без логіки означає, що сам двигун шаблону є менш складним і, отже, має менший слід, і існує менше способів його несподіваної поведінки.
Незважаючи на те, що питання давнє і відповів, я хотів би додати свої 2 ¢ (це може здатися сказом, але це не так, це стосується обмежень і коли вони стають неприйнятними).
Мета шаблону - щось відтворити, а не виконувати бізнес-логіку. Тепер є тонка грань між тим, що не в змозі робити те, що потрібно робити в шаблоні, і мати в них "ділову логіку". Незважаючи на те, що я по-справжньому позитивно ставився до Вуса і намагався ним скористатися, я в кінцевому підсумку не зміг зробити те, що мені потрібно в досить простих випадках.
"Масування" даних (використовувати слова у прийнятій відповіді) може стати справжньою проблемою - не підтримуються навіть прості шляхи (те, на що адресу Handlebars.js). Якщо у мене є дані перегляду, і мені потрібно налаштувати, щоразу, коли мені хочеться щось зробити, оскільки мій шаблон шаблону занадто обмежує, то в підсумку це не допоможе. І це перемагає частину платформи-незалежності, яку вуса претендують на себе; Мені доводиться скрізь дублювати логіку масажу.
Це було сказано, після деяких розчарувань і після спроб інших двигунів шаблонів ми закінчилися створювати свій власний (... ще один ...), який використовує синтаксис, натхненний шаблонами .NET Razor. Він аналізується і компілюється на сервері і генерує просту, автономну функцію JS (фактично як модуль RequireJS), яку можна викликати для "виконання" шаблону, повернувши рядок як результат. Зразок, наданий brad, виглядатиме так приблизно при використанні нашого двигуна (який я особисто вважаю набагато перевершеним у читанні порівняно з вусами та підкресленням):
@name:
<ul>
@for (items) {
<li>@.</li>
}
</ul>
Ще одне обмеження, не обмежене логікою, вдарило нас, коли закликали до угод з вусами Хоча вуса підтримують частки, немає можливості налаштувати дані, що передаються спочатку. Тож замість того, щоб мати змогу створити модульний шаблон і повторно використовувати невеликі блоки, я в кінцевому підсумку робити шаблони з повторним кодом у них.
Ми вирішили це, застосувавши мову запитів, натхненну 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 (із програмою 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 довгих рядка):