Ember: Декларативна шаблонизация c компонируемыми хелперами

Раніше, я згадувала, що помічники (
Helper
) Ember'а були введені в версії 1.13. На мій погляд, помічники одні з найбільш корисних, але не часто обговорюваних, функцій Ember.
У моїй лекції Idiomatic Ember на EmberConf 2016, я у деталях розповіла про хелперах, показуючи, як вони можуть бути використані для підключення і суттєвого розширення функціоналу Handlebars.
Вони можуть використовуватися для декларативною шаблонізації — стилю шаблонізації використовує компонируемые дії (composing actions), і надаючи шаблонами більше відповідальності щодо презентаційний логіки.
Разом з колегою Marten Schilstra, DockYard, ми створили аддон ember-composable-helpers. Це пакет декларативних помічників, і з його допомогою можна зменшити кількість шаблонного коду у Вашому додатку. Ви можете встановити його так:
ember install ember-composable-helpers

Один з моїх улюблених помічників у аддоне —
pipe
(і його closure версія,
pipe-action
). Він дозволяє декларативно складати дії в шаблоні, замість створення безлічі варіантів в компоненті:
{{perform-calculation
add=(action "add")
subtract=(action "subtract")
multiply=(action "multiply")
square=(action "square")
}}

{{! perform-calculation/template.hbs }}
<button {{action (pipe add square) 2 4}}>Should be 36</button>
<button {{action (pipe subtract square) 4 2}}>Should be 4</button>
<button {{action (pipe multiply square) 5 5}}>Should be 625</button>

Помічник pipe був натхненний оператором pipe Elixir' (
|>
), який дозволяє написати наступне:
A(B(C(D(E), "F"), "G"), "H")

Як ланцюжок перетворювачів:
E
|> D()
|> C("F")
|> B("G")
|> A("H")

Використовуючи pipe оператор, можна природним чином висловити
E
передається функції
D
, потім отримане значення передається
C
в якості першого аргументу, і так далі. Я думаю, ми можемо погодитися, що pipe версія набагато легше для читання!
Якщо б Ви тільки знали міць хелперів
Ви можете подумати, що це помічник примітивна
KeyWord
конструкція, яка використовує Ember і HTMLBars для розширення виразів, наданих Handlebars.
На самому базовому рівні, Handlebars відповідає за компіляцію
hbs
шаблонів HTML:
<p>{{myText}}</p>
<!-- відбудеться створення в: -->
<p>Hello world!</p>

Ember і HTMLBars будується поверх цього, додаючи корисні вирази на зразок
action
,
mut
,
get
та
hash
. Насправді, всі знайомі хелпери, які ви використовуєте (від
each
component
є частиною HTMLBars!
Ember Helpers працюють на більш високому рівні, ніж HTMLBars helpers, і можуть бути використані для створення нових виразів в Ember, дозволяючи ефективно розширити шаблонизацию з власною поведінкою.
Все залежить від обставин
Більш досвідчені або консервативні розробники могли б порахувати це небезпечним: при всій своїй корисності для кінцевих користувачів, він також може відкрити можливості для зловживань.
Для прикладу, в Elixir, макроси можуть бути використані для розширення мови, але не рекомендується для реального використання. Це було закріплено в чудовій книзі Chris McCord Метапрограмування на Elixir – "Правило 1: Не використовувати макроси".
На щастя, помічники не настільки могутні як макроси Elixir, і грають важливу роль в моделі програмування Ember. На відміну від макросів, які дозволяють достукатися до AST, використання Ember помічника для розширення презентаційної логіки прийнятно поки ми не зловживаємо цим, і це та особливість, де досвід вступає в гру. Так що використовуйте хелпери з розумом.
Приберіть геть Вашу логіку з мого газону
Деякі люди можуть відчувати дискомфорт при використанні аддонов, що містять помічники, з-за неправильного уявлення про те, що вони привносять дуже багато логіки в шаблони, і воліють тримати їх вільними від неї.
В якості кращої практики, ми повинні утриматися від складної логіки в шаблонах, а також використання вкладених конструкцій на зразок цієї:
{{#unless (or (and (gte value 0) (lt value 0.0001))
(and (lt value 0) (not allowNegativeResults)))}}
...
{{/unless}}

Замість цього використовуйте обчислювані властивості (computed property).
У той же час, зберігати свої шаблони на 100% вільними від логіки дуже важко – Ви, найімовірніше вже використовуєте логічні помічники зразок
if/else
або
unless
. Можна легко випустити з уваги той факт, що кількість логіки в шаблоні строго не визначено.
Назад у майбутнє
ember-composable-helpers
, насправді, не значно збільшить кількість логіки в шаблонах, якщо правильно використовувати, він інкапсулює логіку подання всередину цих помічників, і в багатьох випадках може допомогти Вам ліквідувати надлишковий код в компонентах або контролерах.
Наприклад, Ви могли б написати щось подібне у вашому додатку:
import Ember from 'ember';

const {
Component,
computed: { filterBy, setDiff },
set
} = Ember;

export default Component.extend({
activeEmployees: filterBy('employees', 'isActive'),
inactiveEmployees: setDiff('employees', 'activeEmployees')
});

Досить поширена практика, мати "компонент-посередник" для використання в інших компонентах. За допомогою
ember-composable-helpers
можна писати такі конструкції безпосередньо в шаблоні, де все абсолютно зрозуміло:
<h2>Active Employees</h2>
{{#each (filter by "isActive" engineers) as |employee|}}
{{employee.name}} is active!
{{/each}}

<h2>Inactive Employees</h2>
{{#each (reject-by "isActive" engineers) as |employee|}}
{{employee.name}} is inactive!
{{/each}}

Ви можете думати про компонируемых помічниках як свого роду обчислюваних макро властивостях, які можна використовувати і створювати безпосередньо в шаблоні. І оскільки Ви можете створювати суб-вираження в Ember, вони можуть стати потужною конструкцією для зменшення шаблонного коду в додатку.
З урахуванням вище сказаного, пам'ятайте, не надто захоплюйтеся глибокої вкладеністю!
Найкраще рішення
Як і будь-які інші інструменти програмування, важливо проявляти здоровий глузд і використовувати їх з розумом.
Якщо Ви можете щось зробити, не означає, що ви повинні.
Добре написаний рівень представлення(view layer) означає, що шаблони повинні бути декларативними (все очевидно), наскільки це можливо, а не те, що ми повинні уникати логіки взагалі.
Тим не менш, ми не виступаємо за переміщення всієї своєї логіки в шаблон — знову ж таки, кількість логіки в шаблоні строго не регламетировано.
Якщо Ви хочете побачити, як аддон використовується, Katherin Siracusa написала відмінну статью про те, як вона використовує
ember-composable-helpers
в AlphaSights:
Даний патерн дозволяє виконувати операції над даними і в далнейшем більш допоміжні, короткострокові дії, що постійно виникають у нашому додатку. Використовуючи компонируемые хелпери, ми можемо зробити це досить просто, без особливої дублювання і, не турбуючись про небажаних побічних ефектах.
Ви також можете взяти участь в обговоренні на нашому Slack каналі
#e-composable-helpers
.
Як завжди, дякую за увагу!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.