Темы



Готовим свой первый веб-компонент

Веб-компоненты (здесь и далее — в целях удобства восприятия — «WC») изобрели умные люди, которым надоело готовить спагетти из шаблонов. WC — это [почти] полностью изолированное от среды выполнения DOM-дерево. Я внимательно прочитал правила сайта, поэтому пересказывать википедию не стану. Если вы не знаете, что такое WC, почитать можно здесь.Tl; dr: демо-страничку компонента, который выводит слайдер с текстом нескольких заметок и кнопками «туда»/«сюда» можно посмотреть прямо сейчас.

WC уже используют многие популярные сайты. Если установить плагин WC, можно посмотреть другими глазами на, например, github:

851d7f557d1d4a45b71a01f7f85c50be.png

выделенное красненьким пунктиром — на картинке выше — WC.

Пока производители браузеров жуют бумагу (на данный момент поддерживают технологию Chrome/Opera и, с оговорками, FF), неравнодушные создают костыли. Первым был, наверное, x-tags от Mozilla (совсем недавно они выкатили библиотеку компонентов Brick, на которую пока смотреть без слез невозможно). Самым удачным костылем был и остается Polymer.

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

Например, в этой заметке мы создадим WC, который будет показывать пользователю несколько статей (слайдер для текстового контента). Без перезагрузки страницы, с предупреждающей загрузкой соседей и прочим блэкджеком. Шаблон страницы при этом будет выглядеть вот так (ну, там еще не относящиеся к делу меты будут, IE хелперы и всякая дребедень, наверное; для всех современных браузеров этого шаблона, впрочем, достаточно):

Постановка задачи Пусть у нас есть сервер, который умеет отдавать json в таком виде: { «href»: «demo.html?0», /* html-ссылка для корректной обработки browser history*/ «caption»: «Title 0», /* заголовок окна */ «prev»: null, /* ссылка на json с предыдущей заметкой */ «next»: «data/data1.json», /* ссылка на json со следующей заметкой */ «text»:»

Header 0

Lorem ipsum …

» /* контент */ } И мы хотим показывать этот контент и навигацию по «предыдущая»/«следующая», поддерживая при этом историю браузера. Для этих целей идеально подойдет WC. Итак, приступим.

Средства достижения цели WC (как и все нынче) принято готовить из рыбы (шаблона, скелета, котельного листа, бойлерплаты). Для генерации рыбы будем использовать Йомена. Документация на Yeoman существует в сети, да она особо и не требуется: все сделано для домохозяек, как КОБОЛ.8aa953253f4584597327fe40a4bae8e6.jpg

Устанавливаем все необходимое (для альтернативных ОС инструкции можно найти у поставщиков), а также генератор шаблонов для полимера:

npm install -g yo bower grunt npm install -g generator-polymer Готовые компоненты для своего проекта можно искать на component.kitchen и customelements.io, но мы будем готовить по своему рецепту.

Создаем папку, пусть будет polymer, в ней создаем подпапку с именем нашего компонента (их принято называть в стиле prefix-name), переходим туда и запускаем генератор:

mkdir -p polymer/mudasobwa-slider && cd $_ && yo polymer: seed Отвечаем на несколько несложных вопросов — и мы почти у цели. Давайте посмотрим, что нам нагенерили.

bower.json index.html demo.html mudasobwa-slider.html mudasobwa-slider.css Отлично. Нам потребуются стандартные компоненты для ajax-вызовов, ну и font-awesome для красивых иконок:

bower install --save Polymer/core-ajax bower install --save 'polymer-fontawesome=rtbenfield/polymer-fontawesome#master' Эта команда скачает пакеты, с зависимостями, и обновит наш манифест. Выполним bower install и полюбуемся на нашу рыбу (любой простейший сервер запускаем в заглавном каталоге polymer (NB! на уровень выше нашего компонента):

python -m SimpleHTTPServer Можно сходить браузером по адресу http://localhost:8000 и полюбоваться на дело рук, пока, правда, не наших. Пора немного и покодировать.

Работа с содержимым Тут все, как мы привыкли: такой же javascript, такой же html. Есть всего несколько вещей, которые стоит знать, чтобы кофмортно себя чувствовать: К свойствам есть доступ через переменную this (из скрипта) и через псевдокод {{ ИМЯ_ПЕРМЕННОЙ }} в html; К дочерним компонентам есть доступ через переменную this.$ (sic!); Публичные свойства — декларируются в свойстве attributes основного тега компонента; У shadow-dom есть дополнительные псевдоэлементы, типа : host Что это все означает? Давайте разберемся по коду. Наибольший интерес представляет собой компонент, который занимается обменом данными с сервером, своего рода controller из концепции MVC. Модель я описал (это json, который мы волшебным образом получаем с сервера, тут WC не помогут), на view остановимся чуть позже.

Controller Наш WC зовут «mudasobwa-content-loader», у него есть видимые свойства (атрибуты) url href article caption prefetch next prev stateable (в polymer.js иногда появляются трудновылавливаемые баги, связанные со «слишком стандартными» именами атрибутов, совсем недавно я чуть не поседел, пока понял, отчего FF молча отказывался иметь дело с компонентом у которого был атрибут «title»; это чинят, но имена атрибутам все равно лучше давать позаковыристей), он невидим, и использует WC «core-ajax» для (сюрприз) ajax-вызовов. Также он содержит два таких же, как он сам компонента для прелоадинга соседей (с выключенной опцией «prefetch», иначе каждый сосед потянет за собой своих соседей и так далее). Параметр «url» будет обновляться автоматически в пределах компонента, например, если мы вызовем this.url = http://example.com, core-ajax об этом узнает (и если бы у него была включена опция «auto», он бы сам вызвал автообновление, а получив новый ответ от сервера — вызвал бы метод нашего компонента contentLoaded). У нас автообновление отключено, чтобы не слать лишние запросы.

Скрипт тоже не особо заковырист. Посмотрим, например, на handler contentLoader:

Рейтинг@Mail.ru