@pankajparkar
Angular
React
Vue
Aurelia
preact
.
.
.
Technical Lead
Synerzip Softech India PVT LTD
@pankajparkar
Angular is ideal for building complete applications
Rob Wormald, Angular Team
But it becomes challenging for scenarios that don't fit in Single Page Application Model
@pankajparkar
@pankajparkar
@pankajparkar
Angular components are tough to use outside Angular
Rob Wormald, Angular Team
@pankajparkar
@pankajparkar
@pankajparkar
@pankajparkar
(1990)
INPUT FORM SELECT
@pankajparkar
BODY A H2 IMG UL LI
(1995)
@pankajparkar
INPUT FORM SELECT
BUTTON VIDEO AUDIO
DIALOG CANVAS TEXTAREA
DATALIST IMG PROGRESS
Input had 8 types when it got introduced
Now input have 22 types
@pankajparkar
(1970)
ls
lpr
cat
grep
sort
chmod
echo
alias
less
more
head
who
time
find
tail
echo
kill
mkdir
pwd
ps
.
.
Do One Thing and Do It Well
source: https://en.wikipedia.org/wiki/Unix_philosophy
@pankajparkar
Web Components are a set of features currently being added by the W3C to the HTML and DOM specifications that allow for the creation of reusable widgets or components in web documents and web applications.
<template id="content">
<h1>Hello World!</h1>
<img src="success.jpg" />
<script>
//some big javascript
</script>
</template>
var content = document.getElementById('content');
var div = document.createElement('div');
var clone = document.importNode(template.content, true);
document.body.appendChild(div);
@pankajparkar
We have similar technique, that used inside `ng-template`
<body>
<div>
<#shadow-root>
<h1 class=”title”></h1>
</shadow-root>
</div>
</body>
We can do this for component using encapsulation set to Native.
@pankajparkar
<body>
<div>Hello, World!</div>
<script>
var host = document.querySelector(‘div’);
var root = host.createShadowRoot();
root.textContent = ‘Hello, Treehouse!’;
</script>
</body>
<head>
<link
rel="import"
href="my-widget.html" />
</head>
This spec is deprecated, this is not going to implement by browsers.
@pankajparkar
<body>
<my-navbar></my-navbar>
<div class="content">
<my-sidebar></my-sidebar>
<my-main-content></my-main-content>
</div>
<my-footer></my-footer>
</body>
@pankajparkar
Custom element should have dash used in their name, they can't be single word
@pankajparkar
@pankajparkar
class FancyDatePicker extends HTMLElement {}
window.customElements
.define(‘fancy-datepicker’, FancyDatePicker);
@pankajparkar
@pankajparkar
class FancyDatePicker extends HTMLElement {
static observedAttributes = [‘current-date’];
attributeChangedCallback(oldV, newV, key){
//update the DOM somehow
}
}
<fancy-datepicker
current-date=”10/10/2017”>
</fancy-datepicker>
const picker = document.querySelector(‘fancy-datepicker’);
picker.setAttribute(‘current-date’, new Date().toString());
Declarative
Imperative
@pankajparkar
class FancyDatePicker extends HTMLElement {
set currentDate(value){
//update the DOM
}
get currentDate(){ … }
}
const fancyDatePicker =
document.querySelector(‘fancy-datepicker’);
fancyDatePicker.currentDate = new Date();
@pankajparkar
const picker = document.querySelector(‘fancy-datepicker’);
const onDateChange = (date) => console.log(date);
picker.addEventListener(‘date-change’, onDateChange);
@pankajparkar
class FancyDatePicker extends HTMLElement {
emitDateChange(details){
let dateChangeEv =
new CustomEvent(‘date-change’,{details});
this.dispatchEvent(dateChangeEv);
}
}
const fancyDatePicker =
document.querySelector(‘fancy-datepicker’);
fancyDatePicker.emitDateChange();
@pankajparkar
class FancyDatePicker extends HTMLElement {
connectedCallback(){ … }
disconnectedCallback(){ … }
attributeChangedCallback(oldV, newV, key){ … }
adoptedCallback(){ … }
}
@pankajparkar
Web Component works out of the box in Angular, it supports by design
<my-angular-app>
<facy-datepicker
[attr.currentDate]=”currentDate”
[placement]=”placement”
(dateChanged)=”dateChanged($event)”>
</my-input>
</my-angular-app>
@pankajparkar
Text
https://developers.google.com/web/fundamentals/web-components/examples/howto-checkbox
Source: http://pascalprecht.github.io/slides/angular-elements/#/14
@pankajparkar
@HostBindings
@Input
@Output
@Lifecycle Hooks
Attributes
Properties
CustomEvent
Reactions
@pankajparkar
@pankajparkar
Angular Component packaged as web component
@pankajparkar
web-component
Angular Component
SkateJS
@pankajparkar
// app.module.ts
import { HelloWorldComponent } from './hello-world';
export const CEComponents = [HelloWorldComponent];
@NgModule({
imports: [BrowserModule],
declarations: CEComponents,
//all custom-element should be here
entryComponents: CEComponents
})
export class CustomElementsModule {
ngDoBootstrap() {} // required in bootstrap module
}
@pankajparkar
import { NgModule, Injector } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { createCustomElement } from '@angular/elements';
import { FancyDatepickerComponent } from './fancy-date-picker/fancy-date-picker.component';
@NgModule({
declarations: [FancyDatepickerComponent],
imports: [BrowserModule],
entryComponents: [FancyDatepickerComponent]
})
export class AppModule {
constructor(private injector: Injector)
ngDoBootstrap(app){
let currentElement = createCustomElement(
FancyDatepickerComponent, {
injector: this.injector
});
customElements.define('vote-cmp', currentElement)
}
}
1
2
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'fancy-datepicker',
templateUrl: './fancy-datepicker.html',
styleUrls: ['./fancy-datepicker.css'],
customElement: true
})
export class FancyDatepickerComponent implements OnInit {
constructor(){}
ngOnInit() {}
}
export class FancyDatepickerComponent {
static ngElementDef = defineElementDef({ ... })
}
<fancy-datepicker
currentDate="21-07-2018">
</fancy-datepicker>
Declarative
Imperative
var fancyDatepicker =
docuement.createElement('fancy-datepicker')
fancyDatepicker.currentDate = '21-07-2018'; // set date
// Change date function call
fancyDatepicker.dateChanged('21-07-2018')
let fancyDatepciker = customElements.get('fancy-datepicker')
let newElemenent = new fancyDatepciker(this);
<fancy-datepicker currentDate="21-07-2018">
<div>
My Project / Transcluded Content
</div>
</fancy-datepicker>
<html>
<head>
...
...
<script src="my-customelement.bundle.js"></script>
...
</head>
<body>
...
<my-ng-component></my-ng-component>
...
</body>
</html>
@pankajparkar
<html>
<head>
...
...
<script src="angular-mini.js"></script>
<script src="my-custom-element.bundles.js"></script>
...
</head>
<body>
...
<my-ng-component></my-ng-component>
...
</body>
</html>
@pankajparkar
Jquery dialog modal example
<html>
<head>
...
...
<script src="jquery.js"></script>
<script src="jquery.datepicker.js"></script>
...
</head>
<body>
...
<input id="my-datepicker" />
<script type="javascript">
$('#my-datepicker').datePicker({
format: 'dd-MM-yyyy'
})
</script>
...
</body>
</html>
@pankajparkar
@pankajparkar
With ZoneJS | Without ZoneJS | |
---|---|---|
Bundle Size | 213kb | 199kb |
Bundle Size | 71kb | 58kb |
@pankajparkar
@pankajparkar
https://bit.ly/write-once-use-everywhere
https://blog.angular.io/the-angular-team-at-angularmix-2d56fd7fde65
https://github.com/angular/angular/issues/21706
http://slides.com/andreiantal/ng-europe_angular-elements#/33
http://slides.com/andreiantal/ng-europe_angular-elements#/3
https://github.com/andrei-antal/ng-europe-demo-angular-elements (Thanks Andrei Antal)
https://github.com/pankajparkar/ng-india-angular-elements-demo
https://github.com/pankajparkar/ng-india-vueapp
https://github.com/pankajparkar/ng-india-reactapp
https://medium.com/@ezekizibzibadze/angular-and-web-components-a-k-a-angular-elements-e009b057cd75
https://en.wikipedia.org/wiki/Unix_philosophy
web-component
Angular Component