Angular Elements
Andrei Antal
ngBucharest
ng-europe
2 february 2018
Bucharest, Romania
organizer for ngBucharest
@ngBucharest
groups/angularjs.bucharest
<body>
....
<my-datepicker date="02/02/2018"></my-datepicker>
...
</body>
Exposes:
Encapsulates
const myPicker = document.querySelector('my-dateicker');
elem.addEventListener('date-change', ev => { /* change */});
<angular-app>
...
<my-datepicker
[attr.locale]="someLocale"
[date]="someDate"
(dateChange)="changeDate()"
>
</my-datepicker>
...
</angular-app>
<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>
- Angular Components packaged
as Web Components -
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
Bridging Angular and DOM APIs
@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}?.`);
}
}
import { MyNgComponent } from './ng-component';
@NgModule({
imports: [BrowserModule],
declarations: [MyNgComponent],
entryComponents: [MyNgComponent]
})
export class CustomElementsModule {
ngDoBootstrap() {}
}
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);
})
<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>
<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>
fingers crossed!
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>
);
}
}
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);
Angular dynamic pages talk - AngularConnect 2017
Ward Bell and Jesus Rodriguez
Angular docs - angular.io
@andrei_antal
Reach me at:
antal.a.andrei@gmail.com
#community4thewin