В моей предыдущей статье Предварительный просмотр Polymer 3.0 - Создание мини-карточной игры мы использовали предварительный просмотр Polymer 3.0 для создания пользовательских элементов для нашей мини-карточной игры.
Поскольку Angular хорошо работает с пользовательскими элементами (как упоминалось в https://custom-elements-everywhere.com/, 100% тесты пройдены), давайте попробуем смешать их вместе!
Я также хотел бы воспользоваться этой возможностью, чтобы представить потрясающий Angular и моим друзьям из Polymer. :)
Обратите внимание: -
Пользовательские элементы ≠ Полимер
Пользовательские элементы - это часть спецификации веб-компонента, это возможность создания вашего собственного пользовательского HTML. Он изначально был и будет частью браузера. Полимер - это один из инструментов, который упрощает создание нестандартных элементов. Есть много других способов написать собственные элементы. Более подробное объяснение здесь: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Custom_Elements.
Вот ссылки на:
- демо: https://ng-poly-game.netlify.com/
- исходный код: https://github.com/chybie/ng-polymer-game
Компонентная структура
Давайте посмотрим на нашу структуру компонентов:
Мы создадим новый app component
в Angular, повторно используя другие 4 пользовательских элемента (my-top-bar
, my-top-message
, my-cards
, my-pop-up-modal
), которые мы создали с помощью Polymer 3.0 Preview в предыдущем сообщении.
И снова обзор наших компонентов.
Настройка проекта
Настроить проект в Angular так же просто, как ABC.
A. Установите CLI глобально
// npm npm install @angular/cli -g // or yarn yarn global add @angular/cli
Б. Создание нового проекта с помощью интерфейса командной строки
ng new <your-project-name>
C. Запустите проект, посмотрите его вживую по адресу http: // localhost: 4200.
// npm npm start // or yarn yarn start
Да, это так просто. Angular CLI выполняет все разные задачи за вас (конечно, всегда полезно узнать, что именно он сделал, тогда вы оцените больше). Это похоже на Polymer CLI. Люблю все интерфейсы командной строки! ❤
Включение пользовательских элементов
Включение пользовательских элементов так же просто, как включение файла Javascript.
- Создайте папку
scripts
- Включите наш файл пользовательских элементов в папку
scripts
.
Откуда этот файл? Это из нашего предыдущего поста, это JS-файл, сгенерированный при запуске команды yarn run build
(в dist folder
мы его переименовали с app.<random-hash>.js
на my-custom-elements.js
).
* в реальной производственной среде его следует развернуть как модуль npm и npm install
соответственно.
3. Как и в предыдущем посте, вам потребуются полифиллы, так как не все браузеры пока полностью поддерживают кастомные элементы. Мы будем использовать webcomponents-loader.js
. Установите этот пакет:
// with npm npm install @webcomponents/webcomponentsjs --save // or yarn yarn add @webcomponents/webcomponentsjs
4. Теперь у нас есть эти два файла в нашем проекте. Нам нужно включить эти два файла как часть сборки. Есть несколько способов сделать это. В Angular самым быстрым способом было бы включить эти пути к файлам в .angular-cli.json
file, свойство assets
следующим образом:
"assets": [ "...", { "glob": "webcomponents-loader.js", "input": "../node_modules/@webcomponents/webcomponentsjs", "output": "./scripts/" }, { "glob": "my-custom-elements.js", "input": "./scripts", "output": "./scripts/" } ]
С помощью приведенных выше строк Angular выберет эти файлы и выведет их в папку scripts
после сборки.
5. Загрузите их в наш index.html
. Добавьте эти две строки:
<!-- index.html --> <script src="scripts/webcomponents-loader.js"></script> <script src="scripts/my-custom-elements.js"></script>
Круто, теперь мы можем использовать эти пользовательские элементы. Перейдем к нашему компоненту приложения.
* Однако при производстве необходимо создать файл (например, vendor.ts
) для импорта всех настраиваемых элементов, а не включать его в тег скрипта.
Шаблон компонента приложения
Давайте посмотрим на наш app.component.html
. Вот код:
сравните с шаблоном Polymer в предыдущем посте:
Никаких больших различий, правда?
Все 4 тега HTML выше - это пользовательские элементы, которые мы создали с помощью Polymer ранее. Подумайте здесь несколько важных замечаний (особенно если вы из Polymer).
- В Angular мы называем настраиваемый элемент компонентом, поэтому вы увидите, что я использую термины «настраиваемый элемент» и «компонент» как синонимы.
- В Polymer настраиваемое событие в шаблоне должно начинаться с on- *. В Angular этого нет. Например, в Polymer мы обрабатываем
reset-clicked
какon-reset-clicked
. В Angular мы можем напрямую связать это сreset-clicked
. Мы используем скобку для привязки событий Angular, например(reset-clicked)
. - В обработчике событий Polymer ДОЛЖНО быть только имя функции без скобок (например,
resetGame
). В Angular все наоборот. Это должно бытьresetGame()
. - Для привязки свойств - пользователь Angular
[]
. Например, мы привязываемtime
верхнего компонента сообщения (в Angular мы называем его «input») к переменнойcurrentTime
с помощью[time]="currentTime"
. - Условный оператор в Angular выглядит проще. Посмотрите на всплывающее модальное окно, используйте Angular
*ngIf
. Вы можете чувствовать себя странно с*
здесь. Позвольте мне объяснить здесь немного подробнее:
В Polymer вам нужно будет написать этот длинный код для условного оператора:
<template is="dom-if" if="..."> <my-pop-up-modal ...></my-pop-up-modal> </template>
Вы определенно можете написать что-то подобное в Angular:
<ng-template [ngIf]="..."> <my-pop-up-modal ...></my-pop-up-modal> </ng-template>
Будьте уверены, что приведенный выше синтаксис является допустимым условным синтаксисом Angular и будет работать точно так, как ожидалось.
Однако, что еще лучше, Angular дает вам ярлык *ngIf
, это syntactic sugar
, поэтому вы можете достичь того же результата с помощью менее сложного синтаксиса.
<my-pop-up-modal *ngIf="..."></my-pop-up-modal>
Разве это не круто? Angular предоставляет довольно подробное объяснение синтаксиса * здесь. Проверить это.
Компонент приложения TS
Затем посмотрим на код нашего компонента:
Логика кода точно такая же, как app component
в моем предыдущем посте. Просто скопируйте его. Здесь следует отметить несколько моментов:
Компонентный класс
В Polymer custom element
должен быть классом. Мы создаем новый элемент, расширяя класс PolymerElement
.
В Angular компонент также является классом. Однако вам не нужно расширяться от какого-либо базового класса, просто используйте декоратор классов @Component
, чтобы пометить его как компонент Angular.
* Decorator в настоящее время находится на этапе 2 TC39 https://tc39.github.io/proposal-decorators/
Шаблон, стиль и название
При определении шаблона в Polymer вам необходимо переопределить геттер template
, css также находится в шаблоне. Имя настраиваемого элемента должно быть в кебабе. Одно назначение элемента - переопределить is
геттер или сделать это во время customElements.define
.
В Angular шаблон может быть встроенным или внешним файлом. Вы можете сделать это, настроив объект метаданных в @Component
декораторе класса, template
или templateUrl
свойстве. В нашем случае мы используем внешний шаблон.
Имя компонента в Angular может иметь вид kebab case my-component
или camel case myComponent
. Мы определяем имя в свойстве метаданных selector
.
Стилизация в компоненте Angular может выполняться как встроенными, так и внешними файлами. Вы можете настроить это с помощью свойства метаданных styleUrls
и styles
. Поскольку мы используем Angular CLI, SCSS и LESS поддерживаются из коробки.
Angular CLI также предоставляет простой способ сгенерировать новый компонент, запустив ng generate component <your-component-name>
. Довольно удобно.
Крючки жизненного цикла
У полимера есть крючки жизненного цикла, как и у Angular. Ближайшим жизненным циклом к Polymer ready
будет Angular ngOnInit
. Ознакомиться с полным списком событий жизненного цикла Angular можно здесь.
Отлично. Мы почти на месте. Остался ОДИН ПОСЛЕДНИЙ ШАГ.
Разрешение настраиваемых элементов
Обновив свою страницу сейчас, вы должны увидеть пустую страницу. Посмотрите на консоль, вы получите длинный список ошибок:
Почему? Это потому что:
my-top-bar
не является компонентом Angular, для этого не создан@Component
класс.- Однако
my-top-bar
- это настраиваемый элемент, который у нас есть. Angular об этом не знает. Следовательно, нам нужно сказать Angular, что «Эй, все в порядке, я знаю, что делаю, у меня есть некоторые пользовательские элементы, о которых вы не знаете, перестаньте выдавать мне ошибку, пожалуйста»)
Откройте ваш app.module.ts
файл, добавьте следующие строки:
Подробнее о схеме здесь: https://angular.io/api/core/NgModule#schemas
Играть!
Большой. Обновите браузер еще раз, все должно работать как шарм.
Вот и все. Удачного кодирования!
Вот ссылки на:
- демо: https://ng-poly-game.netlify.com/
- исходный код: https://github.com/chybie/ng-polymer-game