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

Angular Elements

Angular Elements

Slides from my talk about Angular Elements our first Swiss Angular Meetup
Demo can be found at https://github.com/gassmannT/WorldCupComponent

Thomas Gassmann

September 13, 2018
Tweet

More Decks by Thomas Gassmann

Other Decks in Programming

Transcript

  1. ngComponent als
    wiederverwendbare
    Komponente für beliebige
    JavaScript Apps
    Swiss Angular Meetup 13.09.2018
    Thomas Gassmann @gassmannT

    View Slide

  2. Thomas Gassmann
    Senior Consultant,
    Trainer, Speaker
    thomasgassmann.ch
    @gassmannT

    View Slide

  3. Agenda
    13.09.2018 Swiss Angular Meetup - Angular Elements
    3
    ▪ Intro Angular Elements
    ▪ Web Components
    ▪ Getting started with Angular Elements
    ▪ Outlook v7

    View Slide

  4. Angular Elements
    13.09.2018 Swiss Angular Meetup - Angular Elements
    4

    View Slide

  5. 13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - Angular Elements
    6
    Dependency
    Injection
    Decorators Zones
    Compile Binding Render
    Material Mobile Universal
    CLI Language Service Augury
    ngUpdate
    Router
    Animation
    i18n

    View Slide

  7. 13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - 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. 13.09.2018 Swiss Angular Meetup - Angular Elements 9

    View Slide

  10. 13.09.2018 Swiss Angular Meetup - Angular Elements
    10
    Web Components

    View Slide

  11. Web Components
    13.09.2018 Swiss Angular Meetup - 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. 13.09.2018 Swiss Angular Meetup - Angular Elements
    12

    View Slide

  13. Custom Elements
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - Angular Elements
    14
    class myElement extends HTMLElement {

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

    View Slide

  15. Reactions
    13.09.2018 Swiss Angular Meetup - Angular Elements
    15
    class myElement extends HTMLElement {
    connectedCallback() {
    ...
    }
    disconnectedCallback() {
    ...
    }
    }

    View Slide

  16. Attributes
    13.09.2018 Swiss Angular Meetup - 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. 13.09.2018 Swiss Angular Meetup - Angular Elements
    17

    View Slide

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

    View Slide

  19. 13.09.2018 Swiss Angular Meetup - Angular Elements
    19
    let matches = document.querySelector('app-matches-by-country’);
    matches.country = 'ger';

    View Slide

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

    View Slide

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

    View Slide

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

    => Angular has been designed for this

    View Slide

  23. Enter Angular Elements
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - Angular Elements
    24

    View Slide

  25. Getting started
    13.09.2018 Swiss Angular Meetup - Angular Elements
    25

    View Slide

  26. Platform
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - Angular Elements
    29
    @NgModule({
    imports: [BrowserModule, HttpClientModule],
    declarations: [AppComponent, MatchesTodayComponent],
    entryComponents: [MatchesTodayComponent],
    providers: []
    })
    export class AppModule {

    }

    View Slide

  30. Module
    13.09.2018 Swiss Angular Meetup - 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. 13.09.2018 Swiss Angular Meetup - Angular Elements
    31

    View Slide

  32. Use with Javascript
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - Angular Elements
    35
    Plattform Injector
    (Renderer)
    Module Injector
    (Services)
    Component Injector
    (ElementRef)

    View Slide

  36. Dependency Injection in Angular Elements
    13.09.2018 Swiss Angular Meetup - Angular Elements
    36
    Plattform Injector
    (Renderer)
    Module Injector
    (Services)
    Element Injector
    (ElementRef)
    Element Injector
    (ElementRef)

    View Slide

  37. Module
    13.09.2018 Swiss Angular Meetup - 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. 13.09.2018 Swiss Angular Meetup - Angular Elements
    38
    Dependency Injection works!

    View Slide

  39. Demo
    13.09.2018 Swiss Angular Meetup - Angular Elements
    39

    View Slide

  40. Content Projection
    13.09.2018 Swiss Angular Meetup - Angular Elements
    40

    Hallo Angular Meetup

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

    `
    })
    export class TestComponent {
    }

    View Slide

  41. Shadow DOM
    13.09.2018 Swiss Angular Meetup - Angular Elements
    41
    @Component({

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

    }

    View Slide

  42. Demo
    13.09.2018 Swiss Angular Meetup - Angular Elements
    42

    View Slide

  43. Angular Elements in V6
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - Angular Elements
    44
    @Component({
    selector: 'app-test',
    template: '...',
    customElement: true
    })
    export class TestComponent {
    ...
    }

    View Slide

  45. 13.09.2018 Swiss Angular Meetup - Angular Elements
    45
    How to use it today in non Angular Projects?

    View Slide

  46. Combine bundle in a single file
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - 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
    13.09.2018 Swiss Angular Meetup - Angular Elements
    48

    View Slide

  49. 13.09.2018 Swiss Angular Meetup - Angular Elements
    49
    It is just the beginning. Stay tuned
    with Angular 7

    View Slide

  50. Ressources
    13.09.2018 Swiss Angular Meetup - 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]
    13.09.2018 Swiss Angular Meetup - Angular Elements
    51

    View Slide

  52. View Slide