A look into the future
Angular Elements
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/3945677/logo.png)
Andrei Antal
ngBucharest
ng-europe
2 february 2018
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4417997/angular-elements.gif)
Bonjour!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/3576661/10842292_821353757958028_4788304970537894345_o.jpg)
Andrei Antal
@andrei_antal
- frontend engineer (since i can remember)
- web & JS technologies enthusiast
- perpetual learner
Bucharest, Romania
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/3945659/logo-01.png)
organizer for ngBucharest
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/3945743/download-1.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4325248/download.png)
@ngBucharest
groups/angularjs.bucharest
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4482462/romania.png)
WARNING!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4558682/brainiacmh3.png)
DON'T TRY THIS AT HOME
Angular Labs
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4482616/Screen_Shot_2018-01-04_at_12.17.56_PM.png)
@AngularMIX, October 2017
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4482661/Screen_Shot_2018-01-04_at_12.30.20_PM.png)
@AngularConnect, November 2017
There's no excuse for not using Angular on your next project...
...but it might get challenging to use if your app is not a SPA
Rob Wormald, Angular Team (paraphrase)
Angular Components can be tough to use outside Angular
Rob Wormald, Angular Team
Why components outside of Angular?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4560619/Screen_Shot_2018-01-31_at_8.52.56_AM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/1807123/pasted-from-clipboard.png)
Web Components Standard
HTML Templates
Shadow DOM
HTML Imports
Custom Elements
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/1957785/6bac7cc9fea7563ce267904a33850c6d8cf79c1d8d8269901a8f46dc1737c59c.jpg)
<body>
....
<my-datepicker date="02/02/2018"></my-datepicker>
...
</body>
Exposes:
- attributes/properties
- bindable events
Encapsulates
- template (structure)
- styles
- logic
const myPicker = document.querySelector('my-dateicker');
elem.addEventListener('date-change', ev => { /* change */});
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4417845/Screen_Shot_2017-12-06_at_11.36.33_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4482846/1_PgppNaI9YmbRFz2mIkIkOQ.png)
Web Components work with Angular out of the box
<angular-app>
...
<my-datepicker
[attr.locale]="someLocale"
[date]="someDate"
(dateChange)="changeDate()"
>
</my-datepicker>
...
</angular-app>
Why not web components everywhere?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4417990/web_comp_scroll.gif)
Why not Polymer?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4559332/p-logo.png)
<iron-ajax
auto
url="https://www.googleapis.com/youtube/v3/search"
params='{"part":"snippet", "q":"polymer", "key": "YOUTUBE_API_KEY", "type": "video"}'
handle-as="json"
on-response="handleResponse"
debounce-duration="300"></iron-ajax>
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4562778/download.jpg)
Angular Components can be tough to use outside Angular
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4417997/angular-elements.gif)
Angular Elements
- Angular Components packaged
as Web Components -
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/1874570/doubletake.gif)
How does it work?
-
Hosting Angular Components inside Custom Elements (NgElement) - "Angular on the inside, standards on the outside"
-
Bridge between Angular Components and DOM
-
@Inputs - properties
-
@HostBinding - attributes
-
@Outputs - events
-
Lifecycle hooks
-
-
Generate a bundle.js file than you need to include in your app
-
Use it in any application - Angular, static HTML, React, Vue, etc.
-
Self-bootstrapping - drop the element on the page and it works
@Component()
NgElement
@HostBinding
@Input()
@Output()
Lifecycle Hooks
Attributes
Properties
Events
Reactions
"compile"
register as Custom Element
How does it work?
Bridging Angular and DOM APIs
Write your average Angular Component
@Component({
selector: 'ng-component',
template: `<h1>
Hello World, my name is {{myName}} !
</h1>
<button (click)="onClick()">Hi !</button>`,
styles: [...],
encapsulation: ViewEncapsulation.Native,
})
export class NgComponent implements OnInit {
@Input() myName;
@Output() sayHi = new EventEmitter<string>();
ngOnInit() {
this.myName = 'Andrei'
}
onClick() {
this.sayHi.emit(`Yo, wassup ${this.myName}?.`);
}
}
Create the Components Module
import { MyNgComponent } from './ng-component';
@NgModule({
imports: [BrowserModule],
declarations: [MyNgComponent],
entryComponents: [MyNgComponent]
})
export class CustomElementsModule {
ngDoBootstrap() {}
}
Register the custom elements
import { platformBrowserDynamic } from '@angular/platform...';
import { registerAsCustomElements } from '@angular/elements';
import { CustomElementsModule } from './app';
import { MyNgComponent } from './ng-component';
registerAsCustomElements([MyNgComponent], () => {
return platformBrowserDynamic()
.bootstrapModule(CustomElementsModule);
})
Consume the custom element
<head>
...
<script src="my-ngComponent.bundle.js">
</script>
...
</head>
<body>
...
<ng-component></ng-component>
...
</body>
<head>
...
<script src="mini-angular.js"></script>
<script src="my-ngComponent.js"></script>
...
</head>
<body>
...
<my-ngComponent></my-ngComponent>
...
</body>
Looks familiar?
<head>
...
<script src="jquery.min.js"></script>
<script src="jquery.my-datepicker.js">
</script>
...
</head>
<body>
<div class="datepicker"></div>
<script>
$('.datepicker').myDatepicker({...})
</script>
</body>
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4560891/Screen_Shot_2018-01-31_at_10.18.17_AM.png)
DEMO TIME!
fingers crossed!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4419927/Screen_Shot_2017-12-07_at_10.21.20_AM.png)
The magical, reusable web component compiler
import { Component, Prop } from '@stencil/core';
@Component({
tag: 'my-first-component',
styleUrl: 'my-first-component.scss'
})
export class MyComponent {
@Prop() name: string;
@Event() someEvent: EventEmitter;
someEventHandler(data) {
this.someEvent.emit(data);
}
render() {
return (
<p>
My name is {this.name}
</p>
);
}
}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4562439/f0c227dd973557381886bf54b0bfabaa.png)
SkateJS
Effortless custom elements for modern view libraries.
import 'skatejs-web-components';
import { Component, h, prop } from 'skatejs';
import styles from './styles';
class SKTags extends Component {
static props = {
delimiter: prop.string({attribute: true, default: ' '})
}
renderCallback() {
return <div>
<style>{styles}</style>
<div class="wrapper">
<span class="tags"></span>
<input type="text" autofocus="true" class="input"/>
</div>
</div>
}
}
customElements.define('sk-tags', SKTags);
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4563195/Screen_Shot_2018-01-31_at_7.29.16_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4562396/23olen.jpg)
What's next?
What's next?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4562377/Screen_Shot_2018-01-31_at_4.51.55_PM.png)
What's next?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4562389/Screen_Shot_2018-01-31_at_4.52.16_PM.png)
Angular dynamic pages talk - AngularConnect 2017
Ward Bell and Jesus Rodriguez
Angular docs - angular.io
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4417733/Screen_Shot_2017-12-06_at_11.01.07_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4417737/Screen_Shot_2017-12-06_at_11.01.27_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4562341/23ooid.jpg)
The future?
WARNING!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4558682/brainiacmh3.png)
DON'T TRY THIS AT HOME
Merci Beaucoup!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/3945743/download-1.png)
@andrei_antal
Reach me at:
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/4483194/download.png)
antal.a.andrei@gmail.com
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/3945659/logo-01.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/248920/images/3945677/logo.png)
#community4thewin
A look into the future: Angular Elements
By Andrei Antal
A look into the future: Angular Elements
ng-europe 2018 Lightning Talk - A look into the future: Angular Elements by Andrei Antal
- 3,101