Веб-компоненты — новый веб стандарт, разрабатываемый Google. Некоторые считают, что он должен стать трендом в ближайшее время. И я, попробовав его в деле, пожалуй соглашусь с таким мнением.
Подробное описание стандарта: habrahabr.ru/post/152001/
Разработчики дарта не стали ждать и начали реализовывать поддержку веб-компонентов уже сейчас. После того как я об этом узнал, мой интерес к дарту усилился в двойне. Изучив статью с примерами, мне показалось что с веб-компонентами можно творить чудеса:
- количество кода уменьшается,
- из кода убираются DOM-манипуляции,
- в коде остается только логика.
Реальный опыт
Решил опробовать. У меня как раз был мини-проект: тайм трекер. Я написал его исключительно для себя с целью познакомиться с дартом поближе. (Знакомство, кстати, прошло «так себе». На то время и сам дарт и его редактор были очень сырыми.)
Код: github.com/Leksat/time_tracker
Live версия: leksat.me/sites/default/files/time_tracker/web/out/_main.html.html
В качестве стартовой точки программы служит глобальный объект timeTracker
. Главные его обязанности: загрузка и сохранение задач в localStorage. Свойство tasks
содержит список задач, объектов типа Task
.
А вот и код страницы с веб-компонентами.
<div id="main-wrapper" class="{{timeTracker.wrapperClass}}">
<div id="time-tracker">
<div id="tools">
<button data-action="click:timeTracker.createNewTask">New Task</button>
<button data-action="click:timeTracker.deleteAllTasks">Clear all</button>
</div>
<div id="tasks">
<template iterate='task in timeTracker.tasks'>
<div class="task">
<input class="name" type="text" data-bind="value:task.name" />
<input class="time" type="text" data-bind="value:task.time" disabled="{{task.working}}" />
<button data-action="click:task.toggleState">{{task.toggleStateLabel}}</button>
<button data-action="click:task.delete">Delete</button>
</div>
</template>
</div>
</div>
</div>
На первый взгляд выглядит как обычный шаблон. Но только на первый.
data-action="click:timeTracker.createNewTask"
навешиваетonclick
обработчик.data-bind="value:task.name"
связывает связывает свойствоname
объектаtask
со значением свойстваvalue
элементаinput
. Самое приятное, что делается это двунаправленно. При изменении значения пользователем в браузере, свойство объекта в программе будет изменено, и так же наоборот, если свойство объекта изменится в программе, значение элементаinput
обновится автоматически. Стоит заметить, что привязка происходит к конктеному экземпляру объекта. То же самое справелливо и для коллбэков.<template iterate='task in timeTracker.tasks'>
свяжет каждый элемент типа Task в списке со своим шаблоном. И будет следить за изменениями в timeTracker.tasks удаляя или добавляя новые элементы «на лету». Никаких больше лишних обработчиков событий. Все делается само.
Даже в самых простых моментах поведение сильно отличается от «шаблонного». Например, class="{{timeTracker.wrapperClass}}"
не просто присваивает аттрибуту class
значение. Если с помошью инструментов браузера добавить еще один класс, ничего не нарушится, добавленный класс будет «жить» рядом с изначальным. А изначальный будет меняться так же как и раньше. Попробуйте сами, если мое объяснение непонятно.
В итоге, в коде программы нет ни одного момента манипуляций с DOM-элементами. В качестве примера, вот кусок кода который раньше создавал новую задачу. HTML код задачи копировался из шаблона, инициализировались значения input
элементов, навешивались onclick
и onchange
события. После перехода на веб-компоненты, все это было благополучно удалено.
Из неудобств можно отметить разве что необходимость компиляции шаблонов. Но, над автоматизацией этого уже работают.
Мои выводы
Если сложить удачный опыт использования веб-компонентов с последними новостями, получается весьма хорошая перспектива. Все основные фичи дарта уже реализованны в той или иной степени. Теперь дело только за баг-фиксами, ускорением виртуальной машины и уменьшением генерируемого javascript кода.
Автор: Leksat