Slide 1

Slide 1 text

ngComponent als wiederverwendbare Komponente für beliebige JavaScript Apps DWX Nürnberg 2018 Thomas Gassmann @gassmannT

Slide 2

Slide 2 text

Thomas Gassmann Senior Consultant, Trainer, Speaker thomasgassmann.ch @gassmannT 26.06.2018 Angular Elements 3

Slide 3

Slide 3 text

Agenda 26.06.2018 Angular Elements 4 ▪ Intro Angular Elements ▪ Web Components ▪ Getting started with Angular Elements ▪ Outlook v7

Slide 4

Slide 4 text

Angular Elements 26.06.2018 Angular Elements 5

Slide 5

Slide 5 text

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

Slide 7

Slide 7 text

26.06.2018 Angular Elements 8 «[…] 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 26.06.2018 Angular Elements 9 ▪ Enhancing existing HTML Pages ▪ Content Management Systems ▪ Use components in other environments or frameworks ▪ Microfrontends ▪ Reuse components across teams

Slide 9

Slide 9 text

26.06.2018 Angular Elements 10

Slide 10

Slide 10 text

26.06.2018 Angular Elements 11 Web Components

Slide 11

Slide 11 text

Web Components 26.06.2018 Angular Elements 12 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

26.06.2018 Angular Elements 13

Slide 13

Slide 13 text

Custom Elements 26.06.2018 Angular Elements 14 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 26.06.2018 Angular Elements 15 class myElement extends HTMLElement { … } customElements.define('my-element', myElement);

Slide 15

Slide 15 text

Reactions 26.06.2018 Angular Elements 16 class myElement extends HTMLElement { connectedCallback() { ... } disconnectedCallback() { ... } }

Slide 16

Slide 16 text

Attributes 26.06.2018 Angular Elements 17 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

26.06.2018 Angular Elements 18

Slide 18

Slide 18 text

Properties 26.06.2018 Angular Elements 19 class myElement extends HTMLElement { get country() { return this.getAttribute('country'); } set country(val) { this.setAttribute('country', val); } }

Slide 19

Slide 19 text

26.06.2018 Angular Elements 20 let matches = document.querySelector('app-matches-by-country’); matches.country = 'ger';

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Custom Elements in Angular 26.06.2018 Angular Elements 23 => Angular has been designed for this

Slide 23

Slide 23 text

Enter Angular Elements 26.06.2018 Angular Elements 24 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 26.06.2018 Angular Elements 25

Slide 25

Slide 25 text

Getting started 26.06.2018 Angular Elements 26

Slide 26

Slide 26 text

Platform 26.06.2018 Angular Elements 27 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 26.06.2018 Angular Elements 28 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 26.06.2018 Angular Elements 29 @Component({ selector: 'app-matches-today', templateUrl: 'matches-today.component.html’, styleUrls: ['matches-today.component.css’], encapsulation: ViewEncapsulation.Native }) export class MatchesTodayComponent implements OnInit { public matches$: Observable; constructor(private matchService: MatchService) {} ngOnInit() { this.matches$ = this.matchService.getTodayMatches(); } }

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

Module 26.06.2018 Angular Elements 31 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

26.06.2018 Angular Elements 32

Slide 32

Slide 32 text

Use with Javascript 26.06.2018 Angular Elements 33 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 26.06.2018 Angular Elements 34 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 26.06.2018 Angular Elements 35 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 26.06.2018 Angular Elements 36 Plattform Injector (Renderer) Module Injector (Services) Component Injector (ElementRef)

Slide 36

Slide 36 text

Dependency Injection in Angular Elements 26.06.2018 Angular Elements 37 Plattform Injector (Renderer) Module Injector (Services) Element Injector (ElementRef) Element Injector (ElementRef)

Slide 37

Slide 37 text

Module 26.06.2018 Angular Elements 38 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

26.06.2018 Angular Elements 39 Dependency Injection works!

Slide 39

Slide 39 text

Demo 26.06.2018 Angular Elements 40

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

Shadow DOM 26.06.2018 Angular Elements 42 @Component({ … encapsulation: ViewEncapsulation.Native }) export class MatchesTodayComponent implements OnInit { … }

Slide 42

Slide 42 text

Demo 26.06.2018 Angular Elements 43

Slide 43

Slide 43 text

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

Slide 45

Slide 45 text

26.06.2018 Angular Elements 46 How to use it today in non Angular Projects?

Slide 46

Slide 46 text

Combine bundle in a single file 26.06.2018 Angular Elements 47 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 26.06.2018 Angular Elements 48 const fs = require('fs-extra'); const concat = require('concat'); (async function build() { const files = [ './dist/dwxComponent/runtime.js’, './dist/dwxComponent/scripts.js’, './dist/dwxComponent/polyfills.js’, './dist/dwxComponent/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 26.06.2018 Angular Elements 49

Slide 49

Slide 49 text

26.06.2018 Angular Elements 50 It is just the beginning. Stay tuned with Angular 7

Slide 50

Slide 50 text

Ressources 26.06.2018 Angular Elements 51 ▪ 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] 26.06.2018 Angular Elements 52

Slide 52

Slide 52 text

No content