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

ngComponent als wiederverwendbare Komponente fü...

ngComponent als wiederverwendbare Komponente für beliebige JavaScript Apps

Slides from my presentation about Angular Elements at Developer Week (DWX) 2018 in Nürnberg, Germany.
Demo can be found at https://github.com/gassmannT/WorldCupComponent

Thomas Gassmann

June 26, 2018
Tweet

More Decks by Thomas Gassmann

Other Decks in Technology

Transcript

  1. Agenda 26.06.2018 Angular Elements 4 ▪ Intro Angular Elements ▪

    Web Components ▪ Getting started with Angular Elements ▪ Outlook v7
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. Custom Elements 26.06.2018 Angular Elements 14 Custom elements share the

    same API surface as native DOM objects: ▪ Attributes ▪ Properties ▪ Methods ▪ Events
  8. Create and Define a Custom Element 26.06.2018 Angular Elements 15

    class myElement extends HTMLElement { … } customElements.define('my-element', myElement);
  9. Reactions 26.06.2018 Angular Elements 16 class myElement extends HTMLElement {

    connectedCallback() { ... } disconnectedCallback() { ... } }
  10. 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 } } }
  11. Properties 26.06.2018 Angular Elements 19 class myElement extends HTMLElement {

    get country() { return this.getAttribute('country'); } set country(val) { this.setAttribute('country', val); } }
  12. Custom Events 26.06.2018 Angular Elements 21 class myElement extends HTMLElement

    { emitCountryChange() { this.dispatchEvent( new CustomEvent('country-change', { detail: this.country })); } }
  13. Custom Elements in Angular 26.06.2018 Angular Elements 23 <app-matches-by-country [country]="sui"

    (countryChanged)="foobar($event)" > </app-matches-by-country> => Angular has been designed for this
  14. 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
  15. 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
  16. 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
  17. 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<Match[]>; constructor(private matchService: MatchService) {} ngOnInit() { this.matches$ = this.matchService.getTodayMatches(); } }
  18. Module 26.06.2018 Angular Elements 30 @NgModule({ imports: [BrowserModule, HttpClientModule], declarations:

    [AppComponent, MatchesTodayComponent], entryComponents: [MatchesTodayComponent], providers: [] }) export class AppModule { … }
  19. 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); } }
  20. 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');
  21. 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);
  22. 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; }
  23. Dependency Injection in Angular Elements 26.06.2018 Angular Elements 37 Plattform

    Injector (Renderer) Module Injector (Services) Element Injector (ElementRef) Element Injector (ElementRef)
  24. 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); } }
  25. Content Projection 26.06.2018 Angular Elements 41 <app-test> <span>Hallo DWX</span> </app-test>

    @Component({ selector: 'app-test’, template: ` <ng-content></ng-content> ` }) export class TestComponent { }
  26. Shadow DOM 26.06.2018 Angular Elements 42 @Component({ … encapsulation: ViewEncapsulation.Native

    }) export class MatchesTodayComponent implements OnInit { … }
  27. 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.
  28. Outlook V7 26.06.2018 Angular Elements 45 @Component({ selector: 'app-test', template:

    '...', customElement: true }) export class TestComponent { ... }
  29. 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
  30. 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!'); })();