Введение в Angular Elements

Dec 23, 2018

Angular Elements - разработан с целью показать, что Angular-компоненты можно использовать отдельно (без приложения).

Презентация от Pascal Precht (в которой также хорошо показано как работают HTML Web Components) Angular Elements

Что включает в себя концепция Web Components:

Основа Angular Elements лежит в парадигме HTML Web Components - HTML Web Components применяются с целью унификации веба (то есть мы можем расширять спецификацию и писать свои элементы).

  • Использование шаблонов в HtML
  • HTML imports
  • Shadow DOM - DOM и Style инкапсуляция
  • Custom (пользовательские) элементы - расширяют браузерный словарный запас!

На данных пользовательских элементах можно использовать:

  • Attributes
  • Properties
  • Methods
  • Events

Каким образом это делается (как мы декларируем наш элементв DOM)?

С помощью глобального объекта customElements мы декларируем наш элемент в DOM'е ( CustomElementRegistry.define() ). Для этого мы пишем класс, который является наследником от HTMLElement:

class LoadingSpinner extends HTMLElement {
  ...
}

customElements.define('loading-spinner', LoadingSpinner);

Преимущества Custom Element в том, что мы можем вешать на них кастомные addEventListener (смотрите презентацию Pascal Custom Events (pascalprecht/27)):

class LoadingSpinner extends HTMLElement {
  ...
  emitModeChange() {
    this.dispatchEvent(new CustomEvent('mode-change', {
      detail: this.mode
    }));
  }
}
let spinner = document.querySelector('loading-spinner');
spinner.addEventListener('mode-change', event => { ... });

Custom Element внутри Angular

    <loading-spinner
            [mode]="mode"
            [attr.mode]="mode"
            (modeChange)="doSomething($event)"
            [value]="progress">
    </loading-spinner>

Angular и Custom Elements:

Angular и Custom Elements довольно похожи (Angular and Custom Elements (pascalprecht/29)):

    @HostBinding() 	→ 	Attributes
    @Input() 	→ 	Properties
    @Output() 	→ 	CustomEvent()
    Lifecycle Hooks 	→ 	Reactions

Напишем свой Angular Element

  1. Сперва необходимо создать какой-либо компонент, чтобы далее мы могли завернуть его в Custom Elements для дальнейшего использования.
  2. Данный компонент необходимо прописать в entryComponents (где прописываются динамические компоненты).
  3. Далее необходимо добавить модуль @angular/elements (команда ниже установит npm-пакеты, внесет изменения в Angular cli): ng add @angular/elements
  4. Зарегестрируем компонент в конструкторе модуля
import { createCustomElement } from '@angular/elements';
// Angular Element:
import { TestAngularElComponent } from './test-angular-el/test-angular-el.component';


    // ...
    entryComponents: [
        TestAngularElComponent
    ],
    // ...
    providers: [
    // ...
    ]
})
export class PhrasesModule {

    // injector обязателен
    constructor(injector: Injector) {
        // преобразуем Angular компонент, чтобы его можно было использовать в DOM
        const testAngEl = createCustomElement(TestAngularElComponent, { injector });
        customElements.define('test-angular-el', testAngEl);
    }

}

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

Если вы собираете отдельный кастомный элемент без приложения, то вам потребуется использовать метод ngDoBootstrap.

Работаем с кастомным элементом как с DOM-элементом (атрибуты, события)

Мы можем прописать атрибут, принимать его в Angular-элементе и выводить в шаблоне:

    <test-angular-el name="Petr"></test-angular-el>
export class TestAngularElComponent implements OnInit {
    @Input() name;
    constructor() {}
<p>
    test-angular-el works!
</p>
<p>name: {{name}}</p>

Также мы можем генерировать события самим элементом (в Angular), а подписаться на них извне:

В компоненте:

<div (click)="sendCustomEvent($event)">
    <p>name: {{name}}</p>
</div>
    sendCustomEvent(e) {
        this.clicked.emit(e);
    }

Подписываемся в index.html:

<script>
let testAngEl = document.querySelector('test-angular-el');

testAngEl.setAttribute('name', 'Vasya');

testAngEl.addEventListener('clicked', (e) => {
    console.log('e: ', e);
});
</script>

Полифил для IE

npm install @webcomponents/webcomponentsjs --save-dev

Добавьте нижеприведенную строку в файл polyfills.ts:

import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js';

Дополнительно

Статьи в интернете

Неплохая статья на данную тему: Проектируем простой custom web element используя Angular(v6) element

Добавить комментарий