Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Custom Elements with Angular

Custom Elements with Angular

Slides from my talk about Angular Elements at Java Lounge in Zurich
Demo can be found at https://github.com/gassmannT/WorldCupComponent

Thomas Gassmann

September 19, 2018
Tweet

More Decks by Thomas Gassmann

Other Decks in Programming

Transcript

  1. Custom Elements with
    Angular
    JavaLounge 19.09.2018
    Thomas Gassmann @gassmannT

    View Slide

  2. Thomas Gassmann
    Senior Consultant,
    Trainer, Speaker
    thomasgassmann.net
    @gassmannT
    19.09.2018 JavaLounge - Angular Elements
    2

    View Slide

  3. Agenda
    19.09.2018 JavaLounge - Angular Elements
    3
    ▪ Intro Angular Elements
    ▪ Web Components
    ▪ Getting started with Angular Elements
    ▪ Outlook v7

    View Slide

  4. Angular Elements
    19.09.2018 JavaLounge - Angular Elements
    4

    View Slide

  5. 19.09.2018 JavaLounge - Angular Elements
    5
    «Angular is ideal for building complete applications, and
    our tooling, documentation and infrastructure are
    primarily aimed at this case.»
    Rob Wormald, Angular Team

    View Slide

  6. Platform
    19.09.2018 JavaLounge - Angular Elements
    6
    Dependency
    Injection
    Decorators Zones
    Compile Binding Render
    Material Mobile Universal
    CLI Language Service Augury
    ngUpdate
    Router
    Animation
    i18n

    View Slide

  7. 19.09.2018 JavaLounge - Angular Elements
    7
    «[…] but it’s quite challenging to use in
    scenarios that don’t fit that specific Singe Page
    Application model.»
    Rob Wormald, Angular Team

    View Slide

  8. Use case
    19.09.2018 JavaLounge - Angular Elements
    8
    ▪ Enhancing existing HTML Pages
    ▪ Content Management Systems
    ▪ Use components in other environments or frameworks
    ▪ Microfrontends
    ▪ Reuse components across teams

    View Slide

  9. 19.09.2018 JavaLounge - Angular Elements 9

    View Slide

  10. 19.09.2018 JavaLounge - Angular Elements
    10
    Web Components

    View Slide

  11. Web Components
    19.09.2018 JavaLounge - Angular Elements
    11
    Web Components are a set of features added by the W3C
    ▪ HTML Template: Template of the HTML
    ▪ Shadow DOM: DOM and style encapsulation
    ▪ HTML Imports: Imports in HTML
    ▪ Custom Elements: Ability to add to the HTML
    vocabulary

    View Slide

  12. 19.09.2018 JavaLounge - Angular Elements
    12

    View Slide

  13. Custom Elements
    19.09.2018 JavaLounge - Angular Elements
    13
    Custom elements share the same API surface as native
    DOM objects:
    ▪ Attributes
    ▪ Properties
    ▪ Methods
    ▪ Events

    View Slide

  14. Create and Define a Custom Element
    19.09.2018 JavaLounge - Angular Elements
    14
    class myElement extends HTMLElement {

    }
    customElements.define('my-element', myElement);

    View Slide

  15. Reactions
    19.09.2018 JavaLounge - Angular Elements
    15
    class myElement extends HTMLElement {
    connectedCallback() {
    ...
    }
    disconnectedCallback() {
    ...
    }
    }

    View Slide

  16. Attributes
    19.09.2018 JavaLounge - Angular Elements
    16
    class myElement extends HTMLElement {
    static get observedAttributes() {
    return ['country'];
    }
    attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'country') {
    // do something with newValue
    }
    }
    }

    View Slide

  17. 19.09.2018 JavaLounge - Angular Elements
    17

    View Slide

  18. Properties
    19.09.2018 JavaLounge - Angular Elements
    18
    class myElement extends HTMLElement {
    get country() {
    return this.getAttribute('country');
    }
    set country(val) {
    this.setAttribute('country', val);
    }
    }

    View Slide

  19. 19.09.2018 JavaLounge - Angular Elements
    19
    let matches = document.querySelector('app-matches-by-country’);
    matches.country = 'ger';

    View Slide

  20. Custom Events
    19.09.2018 JavaLounge - Angular Elements
    20
    class myElement extends HTMLElement {
    emitCountryChange() {
    this.dispatchEvent(
    new CustomEvent('country-change', {
    detail: this.country
    }));
    }
    }

    View Slide

  21. 19.09.2018 JavaLounge - Angular Elements
    21
    let matches = document.querySelector('app-matches-by-country’);
    matches.addEventListener('country-change', event => { ... });

    View Slide

  22. Custom Elements in Angular
    19.09.2018 JavaLounge - Angular Elements
    22
    [country]="sui"
    (countryChanged)="foobar($event)"
    >

    => Angular has been designed for this

    View Slide

  23. Enter Angular Elements
    19.09.2018 JavaLounge - Angular Elements
    23
    Provides a bridge from angular concepts to web
    components.
    ▪ @HostBinding() => Attributes
    ▪ @Input() => Properties
    ▪ @Output() => CustomEvents
    ▪ Lifecycle Hooks => Reactions

    View Slide

  24. A lot of framework exists
    19.09.2018 JavaLounge - Angular Elements
    24

    View Slide

  25. Getting started
    19.09.2018 JavaLounge - Angular Elements
    25

    View Slide

  26. Platform
    19.09.2018 JavaLounge - Angular Elements
    26
    Dependency
    Injection
    Decorators Zones
    Compile Binding Render
    Material Mobile Universal
    CLI Language Service Augury
    ngUpdate
    Router
    Animation
    i18n

    View Slide

  27. First Steps
    19.09.2018 JavaLounge - Angular Elements
    27
    Update Angular CLI Update Angular CLI to > 6
    ng new angularElements Create a new Angular CLI project
    ng add @angular/elements Add support for angular elements
    ng g c matchToday -v Native Generate new component

    View Slide

  28. Component
    19.09.2018 JavaLounge - Angular Elements
    28
    @Component({
    selector: 'app-matches-today',
    templateUrl: 'matches-today.component.html’,
    styleUrls: ['matches-today.component.css’],
    encapsulation: ViewEncapsulation.ShadowDom
    })
    export class MatchesTodayComponent implements OnInit {
    public matches$: Observable;
    constructor(private matchService: MatchService) {}
    ngOnInit() {
    this.matches$ = this.matchService.getTodayMatches();
    }
    }

    View Slide

  29. Module
    19.09.2018 JavaLounge - Angular Elements
    29
    @NgModule({
    imports: [BrowserModule, HttpClientModule],
    declarations: [AppComponent, MatchesTodayComponent],
    entryComponents: [MatchesTodayComponent],
    providers: []
    })
    export class AppModule {

    }

    View Slide

  30. Module
    19.09.2018 JavaLounge - Angular Elements
    30
    export class AppModule {
    constructor(private injector: Injector) {}
    ngDoBootstrap() {
    const el1 = createCustomElement(
    MatchesTodayComponent,
    { injector: this.injector });
    customElements.define('app-matches-today', el1);
    }
    }

    View Slide

  31. 19.09.2018 JavaLounge - Angular Elements
    31

    View Slide

  32. Use with Javascript
    19.09.2018 JavaLounge - Angular Elements
    32
    const matchesToday = document.createElement('app-
    matches-today');
    document.body.appendChild(matchesToday);
    matchesToday.country = 'SUI';
    matchesToday.setAttribute('country', 'GER');

    View Slide

  33. Use with Custom Element API
    19.09.2018 JavaLounge - Angular Elements
    33
    const MatchToday = document.get('app-matches-today’);
    const matchToday = new MatchToday();
    // or
    const matchToday = new MatchToday(differencInjector);

    View Slide

  34. Angular Elements are the Host Element
    19.09.2018 JavaLounge - Angular Elements
    34
    export class TestComponent implements OnInit {
    constructor(el: ElementRef) {
    el.nativeElement // <- Angular Element
    }
    @HostListener('click’)
    onHostClick($event) { ... }
    @HostBinding('attr.selected')
    isActive: boolean;
    }

    View Slide

  35. Dependency Injection
    19.09.2018 JavaLounge - Angular Elements
    35
    Plattform Injector
    (Renderer)
    Module Injector
    (Services)
    Component Injector
    (ElementRef)

    View Slide

  36. Dependency Injection in Angular Elements
    19.09.2018 JavaLounge - Angular Elements
    36
    Plattform Injector
    (Renderer)
    Module Injector
    (Services)
    Element Injector
    (ElementRef)
    Element Injector
    (ElementRef)

    View Slide

  37. Module
    19.09.2018 JavaLounge - Angular Elements
    37
    export class AppModule {
    constructor(private injector: Injector) {}
    ngDoBootstrap() {
    const el1 = createCustomElement(
    MatchesTodayComponent,
    { injector: this.injector });
    customElements.define('app-matches-today', el1);
    }
    }

    View Slide

  38. 19.09.2018 JavaLounge - Angular Elements
    38
    Dependency Injection works!

    View Slide

  39. Demo
    19.09.2018 JavaLounge - Angular Elements
    39

    View Slide

  40. Content Projection
    19.09.2018 JavaLounge - Angular Elements
    40

    Hallo JavaLounge

    @Component({
    selector: 'app-test’,
    template: `

    `
    })
    export class TestComponent {
    }

    View Slide

  41. Shadow DOM
    19.09.2018 JavaLounge - Angular Elements
    41
    @Component({

    encapsulation: ViewEncapsulation.ShadowDom
    })
    export class MatchesTodayComponent implements OnInit {

    }

    View Slide

  42. Demo
    19.09.2018 JavaLounge - Angular Elements
    42

    View Slide

  43. Angular Elements in V6
    19.09.2018 JavaLounge - Angular Elements
    43
    ▪ It is just the beginning
    ▪ Size is too big for shipping in non Angular projects
    ▪ Will be much better with Ivy (V7)
    ▪ Will be much easier with V7
    ▪ Browser Support.

    View Slide

  44. Outlook V7
    19.09.2018 JavaLounge - Angular Elements
    44
    @Component({
    selector: 'app-test',
    template: '...',
    customElement: true
    })
    export class TestComponent {
    ...
    }

    View Slide

  45. 19.09.2018 JavaLounge - Angular Elements
    45
    How to use it today in non Angular Projects?

    View Slide

  46. Combine bundle in a single file
    19.09.2018 JavaLounge - Angular Elements
    46
    npm install concat --save-dev Install package concat
    npm install fs-extra --save-dev Install package fs-extra
    "build:elements": "ng build --prod --output-
    hashing none && node build-elements.js"
    Add script command

    View Slide

  47. build-elements.js
    19.09.2018 JavaLounge - Angular Elements
    47
    const fs = require('fs-extra');
    const concat = require('concat');
    (async function build() {
    const files = [
    './dist/WorldCupComponent/runtime.js',
    './dist/WorldCupComponent/polyfills.js',
    './dist/WorldCupComponent/main.js'
    ];
    await fs.ensureDir('elements’);
    await concat(files, 'elements/world-cup.js');
    console.info('Wold Cup Element created successfully!');
    })();

    View Slide

  48. Demo
    19.09.2018 JavaLounge - Angular Elements
    48

    View Slide

  49. 19.09.2018 JavaLounge - Angular Elements
    49
    It is just the beginning. Stay tuned
    with Angular 7

    View Slide

  50. Ressources
    19.09.2018 JavaLounge - Angular Elements
    50
    ▪ github.com/gassmannT/WorldCupComponent
    ▪ thomasgassmann.net
    ▪ swissangular.com
    ▪ m.trivadis.com/angular
    ▪ angular-academy.ch

    View Slide

  51. Thank you
    Thomas Gassmann
    @gassmannT
    thomasgassmann.net
    [email protected]
    19.09.2018 JavaLounge - Angular Elements
    51

    View Slide

  52. View Slide