Содержание


Создание специальных многоразовых веб-компонентов с помощью Polymer

Comments

В статье Присоединяйтесь к революции веб-компонентов посредством библиотеки Polymer я рассказал о стандартах веб-компонентов W3C и поддерживающих их технологиях и показал, как легко создать адаптируемое и полезное приложение с графическим интерфейсом пользователя, составленное из основных компонентов Polymer (наряду с другими веб-компонентами от сообщества). Роль разработчика как потребителя компонентов хорошо освещена в примерах к этому руководству.

Само же руководство посвящено роли создателя компонентов Polymer: разработчика, который создает готовые многоразовые свободно компонуемые веб-компоненты для использования в своих собственных приложениях или для публикации в открытых репозиториях. Я продемонстрирую последовательность действий по созданию специального веб-компонента <national-sales-explorer>. Этот компонент содержит:

  • механизм пользовательского интерфейса;
  • механизм извлечения информации из сетевого источника данных;
  • механизм отображения на графиках данных об объемах продаж;
  • механизм отображения информации о местонахождении магазинов на интерактивной карте.

Попутно я расскажу о нескольких методах создания компонентов Polymer, которые пригодятся вам в дальнейшей работе.

Мы будем использовать Bluemix для размещения конечной точки REST API и развертывания приложения с помощью шаблона Mobile Cloud. Исходный код находится в IBM DevOps Services, что позволит вам при желании работать исключительно в облаке.

Что вам потребуется

  • IBM ID и пароль
  • Учетная запись Bluemix
  • Современный веб-браузер (предпочтительно Chrome)
  • Если вы хотите разрабатывать и тестировать приложение локально, то потребуется среда разработки Node.js с поддержкой командной строки git

Запустить приложениеПолучить код

Идея компоновки полезных веб- или мобильных приложений из готовых компонентов перестала быть несбыточной мечтой.

Шаг 1. Попытка взаимодействия с приложением

Пример приложения извлекает данные о местонахождении магазинов и объемах продаж из конечной точки REST API, размещенной в Bluemix, посредством Ajax и динамически создает первоначальный пользовательский интерфейс:

Начальный пользовательский интерфейс приложения
Начальный пользовательский интерфейс приложения
  1. Нажмите кнопку Запустить приложение в этом руководстве.
  2. Отрегулируйте ширину окна браузера, сузив его (менее чем до 600 пикселей), чтобы увидеть, как изменяется приложения в ответ на изменение ширины экрана устройства. Чтобы увидеть выдвижную панель при узком экране, нажмите на кнопку «гамбургер» в левом верхнем углу окна.
  3. Выберите другой магазин и посмотрите, как изменится интерактивная карта.
  4. Нажмите кнопку сверху справа на панели инструментов и выберите Sales. Теперь отображается график объемов продаж этого магазина.
  5. С помощью кнопки «гамбургер» выберите разные магазины, и вы увидите цифры объемов продаж каждого из них: Объемы продаж в Сан-Франциско
    Объемы продаж в Сан-Франциско

Шаг 2. Копирование кода или создание своего собственного проекта Mobile Cloud starter

Вы можете скопировать мой код или создавать свое собственное приложение, используя шаблон Bluemix Mobile Cloud (с последующим редактированием).

  • Чтобы скопировать код:
    1. Нажмите кнопку Получить код в этом руководстве. В DevOps Services нажмите кнопку EDIT CODE моего проекта (введите учетные данные DevOps Services, если вы еще не вошли) и выберите пункт меню FORK, чтобы создать новый проект в своем личном кабинете DevOps Services.
    2. Отредактируйте файл manifest.yml и замените по всему файлу dwpolymer именем своего проекта.
    3. Отредактируйте файл app.js и укажите свои собственные значения applicationRoute и applicationId Bluemix (строки 6-10).
  • Чтобы добавить новое Bluemix-приложение, а затем изменить его:
    1. В каталоге Bluemix выберите шаблон Mobile Cloud: Шаблон Mobile Cloud в каталоге Bluemix
    2. Создайте приложение с уникальным именем: Диалоговое окно для создания приложение Mobile Cloud в Bluemix
      Диалоговое окно для создания приложение Mobile Cloud в Bluemix
    3. В ответ на запрос добавьте в новое приложение git-репозиторий DevOps Services. Клонируйте git-репозиторий в свой локальный компьютер с помощью инструмента командной строки git. Затем внесите следующие изменения:
      1. Замените файл app.js одноименным файлом из моего репозитория.
      2. Добавьте в свой репозиторий копию каталога data моего проекта и его содержимого.
      3. Замените каталог public каталогом из моего репозитория.
      4. Отредактируйте файл app.js и укажите свои собственные значения applicationRoute и applicationId Bluemix (строки 6-10).

Шаг 3. Изучение исходных каталогов и их содержимого

Изучение структуры каталогов и ключевых файлов проекта:

  • data/waypoints.json: JSON-документ, содержащий следующую информацию о местонахождении и объемах продаж магазинов:
    shortnamelongitudelatitudefullnamehardwaresoftwareservices
    rh-78.64792935.7866509Роли300180800
    sd-117.207097832.8746129Сан-Диего12008902200
    sf-122.3983437.791296Сан-Франциско20003180200
  • public/dwsalescomp/index.html: основное HTML-приложение, содержащее единственный ключевой специальный HTML-тег, веб-компонент <national-sales-explorer>.
  • public/dwsalescomp/national-sales-explorer.html: реализация специального веб-компонента Polymer; здесь представлен весь код этого компонента.
  • public/dwsalescomp/sales-datasource/sales-datasource.html: невизуальный веб-компонент Polymer, использующий Ajax для доступа к конечной точке REST API на сервере и получения данных о местонахождении и объемах продаж в формате JSON.
  • app.js: часть шаблона Bluemix Node.js Mobile Cloud, отредактированная для обслуживания конечной точки REST API, а также статические HTML-страницы, содержащие приложение и специальные веб-компоненты.

    Файл шаблона app.js настраивает и запускает экземпляр веб-сервера Express. Для обслуживания конечной точки REST API (источник данных) в app.js добавлен следующий код:

    app.get(ibmconfig.getContextRoot()+'/getsalesdata', function(req,res) {
         res.sendfile('data/waypoints.json');
    });

    Чтобы перенаправить корневой URL-адрес доступа к каталогу public/dwsalescomp, в app.js добавлен следующий код:

    app.get('/', function(req, res){
       res.redirect(ibmconfig.getContextRoot() + '/public/dwsalescomp/index.html');
    });
  • public/bower_components/*: библиотека Polymer, основные компоненты Polymer, paper-компонент кнопки меню Polymer и веб-компоненты графиков объемов продаж и карты.
  • public/images/dwlogo.svg: изображение, используемое при создании пользовательского интерфейса выдвижной панели.
  • manifest.yml: манифест для развертывания приложения на Bluemix. (Вы настроили этот файл на шаге 2, если скопировали проект DevOps DevOps.)

Как обслуживаются данные

Компонент <national-sales-explorer> использует невизуальный специальный элемент Polymer <sales-datasource> для получения данных от конечной точки REST API, размещенной в Bluemix:

Шаг 4. Обзор кода

В этом обзоре освещаются ключевые методы создания специальных элементов с помощью библиотеки Polymer.

Структура кода специального веб-компонента Polymer

Посмотрите на структуру файла national-sales-explorer.html. Это общая структура кода специального компонента Polymer:

<link rel='import' href=../...>

... HTML-импорт компонентов, используемых для составления этого компонента ...

<polymer-element name=national-sales-explorer>
<template>
<style>
... используемые CSS-стили инкапсулированы в компонент ...
</style>

... фактическая компоновка компонента, HTML-элементов и других веб-компонентов ...

</template>
<script>

.. регистрация веб-компонента JavaScript, прототип компонента Polymer ...
</script>
</polymer-element>

Инкапсуляция CSS-стилей

CSS-стили, определенные в специальном элементе, находятся только в теневой модели DOM элемента и не могут проникать наружу. В данном случае для выбора экземпляра элемента <national-sales-explorer> используется специальный :host selector, а google-map выбирает экземпляр веб-компонента <google-map> внутри <national-sales-explorer>:

<style>
    :host {
      display:block;
    font-family: 'RobotoDraft', sans-serif;
    }
    google-map {
      display: block;
      height: 600px;
    }
    ...
</style>

Привязка шаблонов

На левой выдвижной панели генерируется список местоположений магазинов по данным об их координатах с помощью расширения шаблона Polymer. Для перебора массива значений координат можно использовать элемент <template> с атрибутом repeat:

<template repeat="{{waypoint in waypoints}}">
<core-item icon="explore" label="{{waypoint.fullname}}">
</core-item>
</template>

Привязка событий

При выборе местоположения инициируется событие core-select компонента core-menu. Обработчиком событий в этом случае выступает функция элемента itemSelected. Обработчик указывается с помощью декларативной привязки событий Polymer:

<core-menu id='menu' selected="0" 
on-core-select="{{itemSelected}}">
...
</core-menu>

Двухсторонняя привязка данных

При выборе объемов продаж или местонахождения из раскрывающегося меню на панели инструментов отображаемый контент изменяется. В этом случае никакая декларативная привязка событий Polymer не используется. Вместо этого код задействует двустороннюю декларативную привязку данных Polymer.

При выборе изменяется атрибут selected компонента <my-menu-button> (0 для местоположения и 1 для объемов продаж). Тот же связанный объект modeSelected используется и в элементе selected элемента <core-animated-pages>. Всякий раз при изменении атрибута selected элемента <my-menu-button> изменяется и атрибут selected элемента <core-animated-pages> – вызывая смену содержания:

<my-menu-button id='mode' tool icon="more-vert" selected="{{modeSelected}}" 
valign="bottom" halign="right">
</my-menu-button>

... затем...

<core-animated-pages id=cont selected={{modeSelected}} transition=slide-from-right>
...
</core-animated-pages>

Публикуемые свойства

Еще одна область применения двухсторонней привязки данных – публикуемое свойство waypoints невизуального компонента <sales-datasource>. waypoints становится публикуемым свойством, когда его объявляют атрибутом компонента <sales-datasource>:

<polymer-element name="sales-datasource" attributes="waypoints">
...
</polymer>

Это публикуемое свойство представляет собой привязку к объекту waypoints в пределах <national-sales-explorer>. И когда элемент <sales-datasource> успешно извлекает данные через Ajax, публикуемое свойство обновляется, что приводит к обновлению значения привязанного объекта; так координатные точки заполняются данными:

<sales-datasource id="datasource" waypoints="{{waypoints}}">
...
</sales-datasource>

Определение функций и свойств

В части <script> специальных элементов <national-sales-explorer> и <sales-datasource> имеется вызов Polymer(), который регистрирует компоненты. Второй аргумент этого вызова представляет собой JavaScript-прототип специального элемента и содержит определения функций (методов) и свойств. Пример:

Polymer('global-sales-explorer', 
  {
   created: function() {
               .. initialize properties 
              }, 
   itemSelected: function(event, detail, sender) {
               .. event handler ..
              }
 
  });

Внедрение теневой модели DOM

Как правило, CSS-стили на веб-странице не могут влиять на теневую модель DOM специального элемента. Однако в библиотеке Polymer есть специальный селектор ::shadow, позволяющий выборочно проникать в теневую модель DOM. Например, вот как в index.html стилизуется элемент <core-toolbar> компонента <global-sales-explorer>:

global-sales-explorer::shadow  core-toolbar {
      color: white;
      background: red;
      background-color: darkgray;
    }

Автоматический поиск узла

Вместо того чтобы искать узел внутри DOM-компонента Polymer с помощью document.getElementById(), можно более эффективно разыскивать каждый из элементов, идентификаторы которых находятся внутри одной и той же теневой модели DOM, с помощью встроенного хеша this.$. Например, вот обработчик событий itemSelected в <national-sales-explorer>:

var map = this.$.map;
var scaffold = this.$.scaffold;
var location = this.$.location;
var menu = this.$.menu;

Выделение подкласса (расширение) существующего веб-компонента

Меню выбора местоположения/объемов продаж реализуется с помощью специального элемента <my-menu-button>. Он выполнен путем создания подкласса, или расширения, компонента Polymer <paper-menu-button>. При расширении существующего компонента наследуются все его атрибуты, методы и свойства.

В предыдущей версии приложения для этого меню использовался компонент Polymer <core-menu-button>, но в нем имеется ошибка обновления. Чтобы обойти ее, вместо этого элемента используется элемент Polymer <paper-menu-button>.

В отличие от <core-menu-button>, элемент <paper-menu-button> не публикует свойство selected, поэтому элемент <paper-menu-button> пришлось расширить так, чтобы свойство selected публиковалось:

<polymer-element name="my-menu-button" extends="paper-menu-button" attributes="selected">
<template>
  <shadow></shadow>
</template>
<script>
Polymer('my-menu-button', {
 selected: 0,
 observe: {
  '$.menu.selected' : 'menuSelectedChanged'
 },
 menuSelectedChanged: function (oldValue, newValue) {
  this.selected = newValue;
 }
});
</script>
</polymer-element>

Шаг 5. Развертывание приложения в Bluemix

Если вы скопировали мой репозиторий, нажмите кнопку DEPLOY своего проекта в IDE DevOps Services:

Если же вы создали репозитарий с нуля с помощью шаблона Mobile Cloud и работаете с кодом локально, то можете применить команду git push к исправленному коду, чтобы перенести git-репозиторий в DevOps Services и запустить процесс автоматического развертывания в Bluemix.

Заключение

Создание многоразовых специальных элементов с помощью библиотеки Polymer – довольно простой процесс. Вы компонуете существующие компоненты (из библиотеки Polymer или репозиториев сообщества) и применяете немного «клея» HTML, CSS и JavaScript. Результирующий специальный элемент может быть полностью самодостаточным миниприложением, управляющим своим собственным пользовательским интерфейсом, доступом к данным и бизнес-логикой.

Идея компоновки полезных веб- или мобильных приложений из готовых компонентов перестала быть несбыточной мечтой. Стандарты веб-компонентов W3C, усвоенные и реализованные всеми поставщиками современных браузеров — наряду с усилиями мирового сообщества по созданию внушительного корпуса готовых веб компонентов открытым исходным кодом — начали воплощать эту мечту в жизнь. JavaScript-API и библиотека компонентов Polymer способствуют ускорению этого процесса.


Ресурсы для скачивания


Похожие темы


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура, Облачные вычисления
ArticleID=1015665
ArticleTitle=Создание специальных многоразовых веб-компонентов с помощью Polymer
publish-date=09232015