Публикация Адама Боэрема, впервые опубликованная 28 июля 2015 г. для журнала "Purple, Rock, Scissors".
Для всех фронтенд-разработчиков, которые только начали чувствовать себя комфортно с инструментами прошлой недели, недавно на Google I/O было объявлено, что Полимер Google версии 1.0 собирается модернизировать ваше восприятие виджета. Polymer, известный как Веб-компоненты, оптимизирует процесс внедрения стандарта веб-компонентов и добавляет кросс-браузерную поддержку, что делает Polymer практически готовым к работе.
Чтобы дать лучший пример того, почему Polymer и веб-компоненты так хороши, я проведу вас через процесс создания компонента фотопотока с использованием API из нашего приложения GIF-фотобудки Gifn и объясню каждую часть по ходу дела.
Пошаговое руководство
Для начала создайте новую папку в командной строке, используя:
mkdir polymer_tutorial
А затем войдите в папку, используя:
cd polymer_tutorial
Для установки Polymer мы будем использовать Bower, инструмент управления пакетами для JavaScript. Если у вас не установлен Bower, вы можете сделать это с помощью:
npm install -g bower
а затем инициализируйте Bower.
bower init
Оттуда следуйте инструкциям инструмента. Если вы не знаете, как ответить на вопрос, просто нажмите enter и используйте параметр по умолчанию. После инициализации Bower должен поместить файл bower.json в ваш каталог. Чтобы добавить Polymer в качестве зависимости, выполните следующую команду:
bower install --save Polymer/polymer#^1.0.0
Теперь у вас должна быть папка bower_components/ в вашем каталоге, содержащая Polymer и его зависимости. Теперь добавьте два файла в корневой каталог: файл index.html и файл gifn-feed.html, который будет содержать ваш компонент Polymer. Теперь ваш каталог должен выглядеть примерно так:
polymer_tutorial/ bower_components/ bower.json gifn-feed.html index.html
Во-первых, давайте откроем файл index.html и настроим наш HTML для отображения компонента Polymer. Вот весь HTML-код, необходимый для использования простого компонента.
<!doctype html> <html> <head> <title>Gifn Polymer</title> <script src="bower_components/webcomponentsjs/webcomponents.min.js"></script> <link rel="import" href="gifn-feed.html"> </head> <body> <gifn-feed event="prplhq"></gifn-feed> </body> </html>
Инициализация компонента в файле index.html состоит из трех основных частей. Сначала вам нужно добавить библиотеку webcomponents:
<script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
Эта библиотека требуется для всех компонентов Polymer и любых пользовательских компонентов, которые вы создаете самостоятельно. Существует также меньшая библиотека webcomponents-lite.min.js, которую можно использовать вместо нее, если вы создаете элементы только для браузеров, которые в настоящее время поддерживают API веб-компонентов (например, Chrome 36+). . Далее следует тег ссылки, импортирующий наш веб-компонент gifn-feed для использования.
<link rel="import" href="gifn-feed.html">
И затем наш фактический веб-компонент в использовании:
<gifn-feed event="prplhq"></gifn-feed>
Все выглядит вполне нормально, за исключением фактического веб-компонента. Элемент gifn-feed, очевидно, не является вашим обычным HTML, и event="prplhq" также не является ожидаемым атрибутом. Не бойтесь, все это будет иметь смысл, как только мы начнем конкретизировать компонент.
Давайте начнем. Сначала откройте файл gifn-feed.html и добавьте необходимый базовый элемент Polymer вверху файла:
<link rel="import" href="bower_components/polymer/polymer.html">
Одним из замечательных аспектов Polymer является то, что он позволяет импортировать и расширять элементы очень модульным образом. Помимо необходимого basepolymer.html, вы также можете импортировать iron-ajax.html для простых вызовов Ajax или даже кнопки Material Design с помощью paper-button.html. . Вы можете ознакомиться с некоторыми готовыми к использованию компонентами, созданными Google.
Поскольку gifn-feed будет использоваться в нашем HTML, мы собираемся инициализировать его как модуль DOM следующим образом:
<dom-module id="gifn-feed"> </dom-module>
А теперь самое интересное! Давайте инициализируем компонент Polymer с базовой настройкой внутри тега скрипта.
<dom-module id="gifn-feed"> <script> Polymer({ is: "gifn-feed", properties: { event: String } }); </script> </dom-module>
Атрибут «is:» указывает Polymer искать элемент с тегом gifn-feed, а атрибут «properties:» указывает Polymer искать атрибут «event», который будет иметь строковое значение.
Наш веб-компонент по-прежнему ничего не делает, он просто инициализируется. Чтобы добавить действие к компоненту, вы можете использовать один из обратных вызовов жизненного цикла или, в нашем случае, использовать обратный вызов «готово», когда DOM нашего компонента был инициализирован. Вот компонент gifn-feed с «готовым» обратным вызовом.
<dom-module id="gifn-feed"> <script> Polymer({ is: "gifn-feed", properties: { event: String }, ready: function() { var self = this; var xhr = new XMLHttpRequest(); var baseUrl = 'http://demo.gifn.it'; self.gifns = []; // Send an ajax request to get the gif data xhr.open('GET', baseUrl + '/gif/' + self.event); xhr.send(); xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200){ var gifns = []; var response = JSON.parse(xhr.responseText); //Build out the urls for the 5 latest gifs for(var i = 0; i < 5; i++){ var gifUrl = baseUrl+'/asset/'+self.event +'/'+ response.gifs[i].slug+'.thumb.gif'; gifns.push({ url: gifUrl }); } self.gifns = gifns; } } } }); </script> </dom-module>
Что мы делаем в этой готовой функции, так это делаем Ajax-запрос к Gifn API для получения списка изображений GIF. Затем мы создаем URL-адреса и помещаем их в массив, который установлен для нашего объекта Polymer. Позвольте мне объяснить некоторые из наиболее важных аспектов.
var self = this;
Хотя это обычная практика работы с внутренней областью видимости в функциях JavaScript, особенно важно иметь доступ к родительскому объекту Polymer, чтобы можно было привязать данные к представлению. Вот пример его использования:
xhr.open('GET', baseUrl + '/gif/' + self.event);
Эта строка отвечает за инициализацию Ajax-запроса к нашему API, но именно self.event делает ее действительно особенной. Помните атрибут event="prplhq" в нашем теге gifn-feed? Теперь он напрямую связан с нашим объектом Polymer для использования в JavaScript, шаблоне HTML и даже в CSS нашего компонента. Вот еще один пример:
self.gifns = gifns;
На этот раз вместо того, чтобы брать значение из атрибута элемента нашего компонента, мы создаем массив URL-адресов внутри компонента, который затем можно использовать повсюду. Polymer является гибким в том смысле, что он допускает как одностороннюю, так и двустороннюю привязку данных.
Теперь, когда у нас есть набор данных, давайте создадим представление для нашего компонента. Над нашим тегом script добавьте
<template> </template>
Это базовый тег шаблона, необходимый для всех представлений. Внутри тега шаблона вы можете добавить HTML, другие импортированные веб-компоненты Polymer и даже некоторые специальные вспомогательные элементы, используемые для операторов if и перебора данных. Поскольку у нас есть массив URL-адресов, давайте добавим вспомогательный тег dom-repeat.
<template> <template is="dom-repeat" items="{{gifns}}"> <img src="{{item.url}}" /> </template> </template>
Обратите внимание на значение {{gifns}} в теге элементов? Так вы напрямую получаете доступ к атрибутам, привязанным к вашему объекту Polymer. Поэтому, если вы хотите, вы также можете добавить заголовок для события, например:
<h1>{{event}}</h1>
В случае со специальным элементом dom-repeat требуется атрибут «items», который ссылается на значение массива. Затем элемент dom-repeat будет проходить по массиву в цикле, при этом каждое значение будет доступно с использованием переменной «item».
Увидев завершенное представление, некоторые из вас могут задаться вопросом, почему я решил сделать эту конкатенацию строк беспорядочной в готовой функции.
for(var i = 0; i < 5; i++){ var gifUrl = baseUrl + '/asset/' + self.event + '/' + response.gifs[i].slug + '.thumb.gif'; gifns.push({ url: gifUrl }); }
Вы все, вероятно, согласитесь, что это лучший и более чистый вариант.
<template is="dom-repeat" items="{{gifns}}"> <img src="https://demo.gifn.it/asset/{{event}}/{{item.slug}}.thumb.gif" /> </template>
Однако в настоящее время это невозможно и, вероятно, является одним из самых больших недостатков построителя шаблонов в Polymer 1.0. Конкатенация строк и пробелы с переменными представления в настоящее время не поддерживаются в Polymer. Каждый элемент должен занимать все пространство элемента представления или все пространство строки в атрибуте.
Например, это будет работать:
<h1>Welcome <span>{{name}}</span></h1>
но этого не будет:
<h1>Welcome {{name}}</h1>
Чтобы завершить представление, мы добавим немного CSS в наш компонент, чтобы сделать его немного более красивым. Давайте добавим этот блок стилей над тегами нашего шаблона.
<style> img { display:inline-block; } </style>
Хорошо, может быть, это не это, но я действительно ненавижу плавающие элементы. Еще одна замечательная особенность Polymer заключается в том, что он сохраняет CSS вашего компонента локальным, поэтому вам не нужно беспокоиться о конфликтующих правилах CSS.
И это все! Вот полимерная составляющая целиком.
<link rel="import" href="bower_components/polymer/polymer.html"> <dom-module id="gifn-feed"> <style> img { display:inline-block; } </style> <template> <template is="dom-repeat" items="{{gifns}}"> <img src="{{item.url}}" /> </template> </template> <script> Polymer({ is: "gifn-feed", properties: { event: String }, ready: function() { var self = this; var xhr = new XMLHttpRequest(); var baseUrl = 'http://demo.gifn.it'; self.gifns = []; // Send an ajax request to get the gif data xhr.open('GET', baseUrl + '/gif/' + self.event); xhr.send(); xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200){ var gifns = []; var response = JSON.parse(xhr.responseText); //Build out the urls for the 5 latest gifs for(var i = 0; i < 5; i++){ var gifUrl = baseUrl+'/asset/'+self.event+'/'+response.gifs[i].slug+'.thumb.gif'; gifns.push({ url: gifUrl }); } // Bind the response back to the {{gifns}} repeater self.gifns = gifns; } } } }); </script> </dom-module>
Чтобы просмотреть компонент Polymer, вам необходимо разместить его на каком-либо сервере. Это может быть локальный сервер, Vagrant box, MAMP или один из моих фаворитов быстрой командной строки.
python -m SimpleHTTPServer
Наслаждаться!
Рабочую демонстрацию можно увидеть по адресу http://polymer.gifn.it, а весь исходный код можно просмотреть на моем GitHub по адресу https://github.com/adamboerema/polymertutorial.
Для получения дополнительной документации см.: