Slide 1

Slide 1 text

Custom Elements with Angular JavaLounge 19.09.2018 Thomas Gassmann @gassmannT

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

Angular Elements 19.09.2018 JavaLounge - Angular Elements 4

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

19.09.2018 JavaLounge - Angular Elements 9

Slide 10

Slide 10 text

19.09.2018 JavaLounge - Angular Elements 10 Web Components

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

19.09.2018 JavaLounge - Angular Elements 12

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Create and Define a Custom Element 19.09.2018 JavaLounge - Angular Elements 14 class myElement extends HTMLElement { … } customElements.define('my-element', myElement);

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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 } } }

Slide 17

Slide 17 text

19.09.2018 JavaLounge - Angular Elements 17

Slide 18

Slide 18 text

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); } }

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Custom Elements in Angular 19.09.2018 JavaLounge - Angular Elements 22 => Angular has been designed for this

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

A lot of framework exists 19.09.2018 JavaLounge - Angular Elements 24

Slide 25

Slide 25 text

Getting started 19.09.2018 JavaLounge - Angular Elements 25

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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(); } }

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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); } }

Slide 31

Slide 31 text

19.09.2018 JavaLounge - Angular Elements 31

Slide 32

Slide 32 text

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');

Slide 33

Slide 33 text

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);

Slide 34

Slide 34 text

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; }

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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); } }

Slide 38

Slide 38 text

19.09.2018 JavaLounge - Angular Elements 38 Dependency Injection works!

Slide 39

Slide 39 text

Demo 19.09.2018 JavaLounge - Angular Elements 39

Slide 40

Slide 40 text

Content Projection 19.09.2018 JavaLounge - Angular Elements 40 Hallo JavaLounge @Component({ selector: 'app-test’, template: ` ` }) export class TestComponent { }

Slide 41

Slide 41 text

Shadow DOM 19.09.2018 JavaLounge - Angular Elements 41 @Component({ … encapsulation: ViewEncapsulation.ShadowDom }) export class MatchesTodayComponent implements OnInit { … }

Slide 42

Slide 42 text

Demo 19.09.2018 JavaLounge - Angular Elements 42

Slide 43

Slide 43 text

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.

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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!'); })();

Slide 48

Slide 48 text

Demo 19.09.2018 JavaLounge - Angular Elements 48

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

No content