SlideShare a Scribd company logo
Rachael L Moore
Sr UI Engineer
OpenTable
morewry
Creating GUI
Component APIs
in Angular and Web Components
(speaker notes included)
Kara Erickson
Software Engineer
OpenTable
kara | karaforthewin
Angular Connect
20 & 21 October 2015
ExCel London
London, UK
Custom Elements
Angular 1 Directives
Angular 2 Components
APIs
Periodic Table of HTML Elements
style script
cite
samp sup
ruby bdo
code
pre li dd textarea button progress h6 details tfoot
device video audio track canvas iframe source param object embed map area img
link noscript
q
var
sub
markkbd wbr figure ul dt input output keygen h5 article summary thead
base
rp
abbr
time
b
strong
del
br
figcaption ol dl label option datalist h4 nav command tbody
title
a
meter select aside h2 section caption td
meta
rt
dfn
emi
small ins hr
p div blockquote legend optgroup address h3 header menu th
head
span
fieldset form body h1 colgroup tr
html col table
footer
Periodic Table of HTML Elements
style script
cite
samp sup
ruby bdo
code
pre li dd textarea button progress h6 details tfoot
device video audio track canvas iframe source param object embed map area img
link noscript
q
var
sub
markkbd wbr figure ul dt input output keygen h5 article summary thead
base
rp
abbr
time
b
strong
del
br
figcaption ol dl label option datalist h4 nav command tbody
title
a
meter select aside h2 section caption td
meta
rt
dfn
emi
small ins hr
p div blockquote legend optgroup address h3 header menu th
head
span
fieldset form body h1 colgroup tr
html col table
footer
canvas
GUIs
<select>
<option>Opt 1</option>
</select>
Standard Elements
Standard Elements - DOM Interfaces
var select = $("select")[0];<select>
<option>Opt 1</option>
</select>
Standard Elements - DOM Interfaces
var select = $("select")[0];
select.options
select.options.length
// 1
Standard Elements - DOM Interfaces
<select>
<option>Opt 1</option>
</select>
Standard Elements - DOM Interfaces
var select = $("select")[0];
select.options
select.options.length
// 1
Standard Elements - DOM Interfaces
<select>
<option>Opt 1</option>
</select>
Standard Elements - DOM Interfaces
<select>
<option>Opt 1</option>
<option>Opt 2</option>
</select>
Standard Elements - DOM Interfaces
var select = $("select")[0];
select.add(
new Option("Opt 2")
);
Standard Elements - DOM Interfaces
<select>
<option>Opt 1</option>
<option>Opt 2</option>
</select>
Standard Elements - DOM Interfaces
var select = $("select")[0];
select.add(
new Option("Opt 2")
);
Standard Elements - DOM Interfaces
<*>
<ng-transclude>
<select>
<option>...
<custom-element>
// HTMLElement
// HTMLUnknownElement
// HTMLSelectElement
// HTMLOptionElement
// WHATEVER I WANT!
Elements - DOM Interfaces Elements - DOM Interfaces
<*>
<ng-transclude>
<select>
<option>...
<custom-element>
// HTMLElement
// HTMLUnknownElement
// HTMLSelectElement
// HTMLOptionElement
// WHATEVER I WANT!
Elements - DOM Interfaces Elements - DOM Interfaces
<*>
<ng-transclude>
<select>
<option>...
<custom-element>
// HTMLElement
// HTMLUnknownElement
// HTMLSelectElement
// HTMLOptionElement
// WHATEVER I WANT!
Elements - DOM Interfaces Elements - DOM Interfaces
<*>
<ng-transclude>
<select>
<option>...
<custom-element>
// HTMLElement
// HTMLUnknownElement
// HTMLSelectElement
// HTMLOptionElement
// WHATEVER I WANT!
Elements - DOM Interfaces Elements - DOM Interfaces
<*>
<ng-transclude>
<select>
<option>...
<custom-element>
// HTMLElement
// HTMLUnknownElement
// HTMLSelectElement
// HTMLOptionElement
// WHATEVER I WANT!
Elements - DOM Interfaces Elements - DOM Interfaces
Confirmation Enhancement
Confirmation Enhancement
Confirmation Enhancement
Existing Feature
Existing Feature
Creating GUI Component APIs in Angular and Web Components
Nouns, Adjectives, and Verbs
Nouns, Adjectives, and Verbs
Nouns, Adjectives, and Verbs
Requirements
Pseudocode
Requirements- confirm modal.confirm()
Request Confirmation - Pseudocode
Request Confirmation
Requirements- modal modal.confirm()
<modal />
Confirmation Modal - Pseudocode
Request Confirmation
Confirmation Modal
Requirements- open modal.confirm()
<modal />
modal.open()
Modal Opens - Pseudocode
Request Confirmation
Confirmation Modal
Modal Opens
Modal Content
Modal Content
Modal Content
Modal Content
Modal Content
Requirements- content modal.confirm()
<modal>
<!-- custom -->
</modal>
modal.open()
Custom Modal Content - Pseudocode
Request Confirmation
Confirmation Modal
Modal Opens
Custom Modal Content
Requirements- multiple 2 modal.confirm()
<modal>
<!-- custom -->
</modal>
modal.open()
Multiple Modals - Pseudocode
Request Confirmation
Confirmation Modal
Modal Opens
Custom Modal Content
Multiple Modals
Requirements- close modal.confirm()
<modal>
<!-- custom -->
</modal>
modal.open()
modal.close()
Modal Closes - Pseudocode
Request Confirmation
Confirmation Modal
Modal Opens
Custom Modal Content
Multiple Modals
Modal Closes
Requirements- proceed modal.confirm()
<modal>
<!-- custom -->
</modal>
modal.open()
modal.close()
modal.proceed()
Proceed Afterwards - Pseudocode
Request Confirmation
Confirmation Modal
Modal Opens
Custom Modal Content
Multiple Modals
Modal Closes
Proceed Afterwards
Requirements- callback modal.confirm(callback)
<modal>
<!-- custom -->
</modal>
modal.open()
modal.close()
modal.proceed()
Proceed Afterwards - Pseudocode
Request Confirmation
Confirmation Modal
Modal Opens
Custom Modal Content
Multiple Modals
Modal Closes
Proceed Afterwards
Custom Elements
brought to you by Web Components
Custom Elements
brought to you by Web Components
OTConfirmModal.js
document.registerElement("ot-confirm-modal", {
prototype: {}
});
registerElement - OTConfirmModal.js
document.registerElement("ot-confirm-modal", {
prototype: {}
});
registerElement - OTConfirmModal.js
document.registerElement("ot-confirm-modal", {
prototype: {}
});
registerElement - OTConfirmModal.js
document.registerElement("ot-confirm-modal", {
prototype: {}
});
registerElement - OTConfirmModal.js
document.registerElement("ot-confirm-modal", {
prototype: {}
});
registerElement - OTConfirmModal.js
class OTConfirmModalElement {
};
document.registerElement("ot-confirm-modal", {
prototype: OTConfirmModalElement.prototype
});
class OTConfirmModalElement - OTConfirmModal.js
class OTConfirmModalElement {
};
document.registerElement("ot-confirm-modal", {
prototype: OTConfirmModalElement.prototype
});
class OTConfirmModalElement - OTConfirmModal.js
class OTConfirmModalElement {
};
document.registerElement("ot-confirm-modal", {
prototype: OTConfirmModalElement.prototype
});
class OTConfirmModalElement - OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
};
document.registerElement("ot-confirm-modal", {
prototype: OTConfirmModalElement.prototype
});
extends HTMLElement - OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
};
document.registerElement("ot-confirm-modal", {
prototype: OTConfirmModalElement.prototype
});
extends HTMLElement - OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
...
};
OTConfirmModal.js
Confirmation Modal Template -
<div id="modal">
<div id="overlay"></div>
<section id="dialog">
<svg id="x"></svg>
<button id="cancel">
Cancel
</button>
<button id="confirm">
Confirm
</button>
</section>
</div>
Confirmation Modal Template -
<div id="modal">
<div id="overlay"></div>
<section id="dialog">
<svg id="x"></svg>
<button id="cancel">
Cancel
</button>
<button id="confirm">
Confirm
</button>
</section>
</div>
Confirmation Modal Template -Confirmation Modal Template -
<div id="modal">
<div id="overlay"></div>
<section id="dialog">
<svg id="x"></svg>
<button id="cancel">
Cancel
</button>
<button id="confirm">
Confirm
</button>
</section>
</div>
Confirmation Modal Template -Confirmation Modal Template -
<div id="modal">
<div id="overlay"></div>
<section id="dialog">
<svg id="x"></svg>
<button id="cancel">
Cancel
</button>
<button id="confirm">
Confirm
</button>
</section>
</div>
Confirmation Modal Template -Confirmation Modal Template -
<div id="modal">
<div id="overlay"></div>
<section id="dialog">
<svg id="x"></svg>
<button id="cancel">
Cancel
</button>
<button id="confirm">
Confirm
</button>
</section>
</div>
Confirmation Modal Template -Confirmation Modal Template -
<div id="modal">
<div id="overlay"></div>
<section id="dialog">
<svg id="x"></svg>
<button id="cancel">
Cancel
</button>
<button id="confirm">
Confirm
</button>
</section>
</div>
Confirmation Modal Template -Confirmation Modal Template -
<div id="modal">
<div id="overlay"></div>
<section id="dialog">
<svg id="x"></svg>
<button id="cancel">
Cancel
</button>
<button id="confirm">
Confirm
</button>
</section>
</div>
Confirmation Modal Template -Confirmation Modal Template -
class OTConfirmModalElement extends HTMLElement {
...
createdCallback () {}
};
createdCallback - OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
...
createdCallback () {
// see Content Container talk from ng-conf 
}
};
ng-conf - OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
...
};
OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
...
open () {}
close () {}
};
open & close methods - OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
...
open () {
this.hidden = false;
}
close () {
this.hidden = true;
}
};
hidden property - OTConfirmModal.js
<ot-confirm-modal hidden>
...
</ot-confirm-modal>
OTConfirmModal.js - hidden attribute
...extends HTMLElement {
...
open () {
this.hidden = false;
}
close () {
this.hidden = true;
}
};
OTConfirmModal.js - hidden attribute
class OTConfirmModalElement extends HTMLElement {
...
};
OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
...
};
OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
...
confirm (callback) {
this.onProceed = callback;
this.open();
}
};
confirm - OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
...
};
OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
...
proceed () {
this.close();
this.onProceed();
}
};
proceed - OTConfirmModal.js
class OTConfirmModalElement extends HTMLElement {
createdCallback
open
close
confirm (callback)
proceed
};
Angular-Connect-2015  Pseudocode Summary - OTConfirmModal.js
<ot-confirm-modal id="block">
Blocking will prevent diners from making
reservations online.
</ot-confirm-modal>
Tag - Integration with Application - index.html
...
var blockModal = $("#block")[0];
// blockModal.confirm()
Query DOM - Integration with Application - index.html
...
var blockModal = $("#block")[0];
// blockModal.confirm()
Query DOM - Integration with Application - index.html
...
<button onclick="blockReservations()">
Block Reservations
</button>
Existing Button - Integration with Application - index.html
...
<button onclick="blockModal.confirm(blockReservations)">
Block Reservations
</button>
Confirm Method - Integration with Application - index.html
Summary - Integration with Application - index.html
<ot-confirm-modal id="block">
Blocking will prevent diners from making
reservations online.
</ot-confirm-modal>
$("#block")[0].confirm(blockReservations);
Declarative custom tag <ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
Custom Elements
Custom elements
Declarative custom tag
Imperative access to API
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
$("#id")[0].confirm(cb);
Custom Elements
Custom elements
Declarative custom tag
Imperative access to API
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
$("#id")[0].confirm(cb);
Custom Elements
Custom elements
Angular 1Angular 1
Declarative custom tag
Imperative access to API
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
$("#id")[0].confirm(cb);
Custom Elements
Custom elements
Angular 1Custom elements
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
// Declarative custom tag
$("#id")[0].confirm(cb);
// Flexible imperative API
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
// ?
Angular 1 Directive Communication
?
?
?
Angular 1 Directive Communication
Events
?
?
Event Strategy
Button Modal
Event Strategy
ModalButton
click
Event Strategy
"confirm-me", block
ModalButton
Event Strategy
ModalButton
"confirm-me", block
Event Strategy
Modal
OPEN
Button
Event Strategy
ModalButton
Event Strategy
ModalButton
trigger
$rootScope
AppController
trigger modal
Confirmation Modal - Scope tree
$rootScope
AppController
trigger modal
Confirmation Modal - Scope tree
$broadcast
$rootScope
AppController
trigger modal
Confirmation Modal - Scope tree
$emit
$rootScope
AppController
trigger modal
Confirmation Modal - Scope tree
$rootScope
AppController
trigger modal
Confirmation Modal - Scope tree
$rootScope
AppController
trigger modal
Confirmation Modal - Scope tree
scope.$emit
$rootScope
AppController
trigger modal
Confirmation Modal - Scope tree
scope.$emit $rootScope.$on
$rootScope
AppController
trigger modal
Confirmation Modal - Scope tree
$rootScope.$emit $rootScope.$on
$rootScope
AppController
trigger modal
"confirm-" + modal
Confirmation Modal - Scope tree
"confirm-" + this.id
$rootScope.$emit $rootScope.$on
Events
Name conflicts
Pollute $rootScope
Memory leaks
Angular 1Custom elements
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
// Declarative custom tag
$("#id")[0].confirm(cb);
// Flexible imperative API
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
$rootScope.$emit("confirm-id")
Angular 1Custom elements
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
// Declarative custom tag
$("#id")[0].confirm(cb);
// Flexible imperative API
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
$rootScope.$emit("confirm-id")
// or
<button on-confirm="cb()"
ot-confirm-with="id">
Angular 1 Directive Communication
Events
?
?
Angular 1 Directive Communication
Events
Requiring controller
?
Angular 1 Directive Communication
Events
Requiring controller
?
require: "^someDir"
link: (s,e,a,ctrl) =>{}
<div ng-controller="AppController as App">
<button>Block</button>
<ot-confirm-modal>
Are you sure?
</ot-confirm-modal>
</div>
index.html
<div ng-controller="AppController as App">
<button ot-on-confirm="block()">Block</button>
<ot-confirm-modal>
Are you sure?
</ot-confirm-modal>
</div>
index.html
<div ng-controller="AppController as App">
<button ot-on-confirm="block()">Block</button>
<ot-confirm-modal>
Are you sure?
</ot-confirm-modal>
</div>
index.html
<div ng-controller="AppController as App">
<ot-confirm-modal>
Are you sure?
<button ot-on-confirm="block()">Block</button>
</ot-confirm-modal>
</div>
index.html
<div ng-controller="AppController as App">
<button ot-on-confirm="block()">Block</button>
<ot-confirm-modal>
Are you sure?
</ot-confirm-modal>
</div>
index.html
<div ng-controller="AppController as App">
<ot-confirm-required>
<button ot-on-confirm="block()">Block</button>
<ot-confirm-modal>
Are you sure?
</ot-confirm-modal>
</ot-confirm-required>
</div>
index.html
Controller Strategy
Button
trigger
Modal
Confirm-Required
Controller Strategy
Confirm-Required
require:
"^confirmRequired"
require:
"^confirmRequired"
Button
trigger
Modal
Angular 1Custom elements
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
// Declarative custom tag
$("#id")[0].confirm(cb);
// Flexible imperative API
Angular 1
<ot-confirm-required>
<button ot-on-confirm />
<ot-confirm-modal>
Are you sure?
</ot-confirm-modal>
</ot-confirm-required>
require: "^otConfirmModal",
link: (s, e, a, ctrl) => {
ctrl.confirm(cb);
}
Custom elements
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
// Declarative custom tag
$("#id")[0].confirm(cb);
// Flexible imperative API
Events
Requiring controller
?
Angular 1 Directive Communication
Events
Requiring controller
Service
Angular 1 Directive Communication
Events
Requiring controller
Service
Angular 1 Directive Communication
confirmModal.confirm();
Directive Strategy
ModalButton
Service Strategy
Button
Service Strategy
App
["confirmModal"]
ModalButton
Service Strategy
App
// confirmModal.confirm()
Button
Service Strategy
App
// confirmModal.confirm()
ModalButton
Service Strategy
App
// confirmModal.close()
ModalButton
Service Strategy
App
// confirmModal.close()
Button
open:
index.html
Toggling the modal <button
ng-click="confirm()">
Block
</button>
open:
1. get modal template
$templateCache.$get("...")
index.html
Toggling the modal <button
ng-click="confirm()">
Block
</button>
open:
1. get modal template
2. compile the modal manually
$compile(template)(scope)
index.html
Toggling the modal <button
ng-click="confirm()">
Block
</button>
open:
1. get modal template
2. compile the modal manually
index.html
Toggling the modal <button
ng-click="confirm()">
Block
</button>
<!--
<ot-confirm-modal>
Custom content here.
</ot-confirm-modal>
-->
open:
1. get modal template
2. compile the modal manually
3. add custom content
index.html
Toggling the modal <button
ng-click="confirm()">
Block
</button>
/*
confirmModal.confirm({
callback: this.block,
template: "feature.html"
})
*/
open:
1. get modal template
2. compile the modal manually
3. add custom content
4. append to DOM
index.html
Toggling the modal <button
ng-click="confirm()">
Block
</button>
open:
1. get modal template
2. compile the modal manually
3. add custom content
4. append to DOM
close:
index.html
Toggling the modal <button
ng-click="confirm()">
Block
</button>
open:
1. get modal template
2. compile the modal manually
3. add custom content
4. append to DOM
close:
1. remove element
2. destroy scope
index.html
Toggling the modal <button
ng-click="confirm()">
Block
</button>
Angular 1Custom elements
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
// Declarative custom tag
$("#id")[0].confirm(cb);
// Flexible imperative API
// modal.html
confirmModal.confirm({
callback: block,
template: "modal.html"
});
<button on-confirm="block()"
ot-confirm-with="modal.html">
Events
Require controller
Service
Angular 1 Directive Communication
Events risky implementation
Require controller
Service
Angular 1 Directive Communication
Events risky implementation
Require controller clunky interface
Service
Angular 1 Directive Communication
Angular 2
Yes!
class OtConfirmModal {}
Angular 2
@Component({})
class OtConfirmModal {}
Angular 2
@Component({
selector: "ot-confirm-modal"
})
class OtConfirmModal {}
Angular 2
@Component({
selector: "ot-confirm-modal",
template: ``
})
class OtConfirmModal {}
Angular 2
@Component({
selector: "ot-confirm-modal",
template: `
<div class="modal">
<ng-content></ng-content>
<button>Cancel</button>
<button>Confirm</button>
</div>
<div class="overlay"></div>`
})
class OtConfirmModal {}
Angular 2
@Component({
selector: "ot-confirm-modal",
template: `
<div class="modal" [hidden]="!isOpen">
<ng-content></ng-content>
<button>Cancel</button>
<button>Confirm</button>
</div>
<div class="overlay" [hidden]="!isOpen"></div>`
})
class OtConfirmModal {}
Angular 2
@Component({
selector: "ot-confirm-modal",
template: `
<div class="modal" [hidden]="!isOpen">
<ng-content></ng-content>
<button (click)="close()">Cancel</button>
<button>Confirm</button>
</div>
<div class="overlay" [hidden]="!isOpen"
(click)="close()"></div>`
})
class OtConfirmModal {}
Angular 2
@Component({
selector: "ot-confirm-modal",
template: `
<div class="modal" [hidden]="!isOpen">
<ng-content></ng-content>
<button (click)="close()">Cancel</button>
<button (click)="proceed()">Confirm</button>
</div>
<div class="overlay" [hidden]="!isOpen"
(click)="close()"></div>`
})
class OtConfirmModal {}
Angular 2
@Component({...})
class OtConfirmModal {}
Angular 2
@Component({...})
class OtConfirmModal {
isOpen: boolean = false;
open() { this.isOpen = true; }
close() { this.isOpen = false; }
}
Angular 2
@Component({...})
class OtConfirmModal {
isOpen: boolean = false;
open() { this.isOpen = true; }
close() { this.isOpen = false; }
proceed() {
this.onProceed();
this.close();
}
confirm(callback) {
this.onProceed = callback;
this.open();
}
Angular 2...
@Component({
selector: "app"
})
class App {}
app.ts
@Component({
selector: "app",
template: ``
})
class App {}
app.ts
@Component({
selector: "app",
template: `
<button (click)="">Block</button>
`
})
class App {}
app.ts
@Component({
selector: "app",
template: `
<button (click)="">Block</button>
<ot-confirm-modal>
Are you sure?
</ot-confirm-modal>`
})
class App {}
app.ts
@Component({
selector: "app",
template: `
<button (click)="">Block</button>
<ot-confirm-modal>
Are you sure?
</ot-confirm-modal>`,
directives: [OtConfirmModal]
})
class App {}
app.ts
Local variables
Angular 2 Strategies var-a
#a
<input #a (keyup)>
<p> {{ a.value }} </p>
<ot-confirm-modal #main>
// main OtConfirmModal instance
Pseudocode
@Component({
selector: "app",
template: `
<button (click)="">Block</button>
<ot-confirm-modal>
Are you sure?
</ot-confirm-modal>`,
directives: [OtConfirmModal]
})
class App {}
app.ts
@Component({
selector: "app",
template: `
<button (click)="">Block</button>
<ot-confirm-modal #main>
Are you sure?
</ot-confirm-modal>`,
directives: [OtConfirmModal]
})
class App {}
app.ts
@Component({
selector: "app",
template: `
<button (click)="main.confirm(block)">Block</button>
<ot-confirm-modal #main>
Custom content here.
</ot-confirm-modal>`,
directives: [OtConfirmModal]
})
class App {...}
app.ts
@Component({...})
class App {
block() {
console.log("posted!");
}
}
app.ts
@Component({...})
class App {
_block() {
console.log("posted!");
}
get block(){
return this.block.bind(this);
}
}
app.ts
@Component({
selector: "app",
template: `
<button (click)="main.confirm(block)">Block</button>
<ot-confirm-modal #main>
Custom content here.
</ot-confirm-modal>`,
directives: [OtConfirmModal]
})
class App {...}
app.ts
Angular 2
<ot-confirm-modal #id>
Are you sure?
</ot-confirm-modal>
id.confirm(cb);
Custom elements
<ot-confirm-modal id="id">
Are you sure?
</ot-confirm-modal>
// Declarative custom tag
$("#id")[0].confirm(cb);
// Flexible imperative API
@Component({
selector: "app",
template: `
<button (click)="main.confirm(block)">
Block
</button>
<ot-confirm-modal #main>
Custom content here.
</ot-confirm-modal>`,
directives: [OtConfirmModal]
})
...
app.ts
@Component({
selector: "app",
template: `
<button [confirm-with]="main" (confirm)="block()">
Block
</button>
<ot-confirm-modal #main>
Custom content here.
</ot-confirm-modal>`,
directives: [OtConfirmModal]
})
...
app.ts
@Directive({})
class OtConfirmWith {}
Angular 2
@Directive({
selector: "[ot-confirm-with]"
})
class OtConfirmWith {}
Angular 2
scope: {
modal:"=otConfirmWith"
}
@Directive({
selector: "[ot-confirm-with]"
})
class OtConfirmWith {
@Input("ot-confirm-with") modal: OtConfirmModal;
}
Angular 2
scope: {
modal:"=otConfirmWith"
}
@Directive({
selector: "[ot-confirm-with]"
})
class OtConfirmWith {
@Input("ot-confirm-with") modal: OtConfirmModal;
}
Angular 2
$element.on("click",
requestConfirm)
@Directive({
selector: "[ot-confirm-with]"
})
class OtConfirmWith {
@Input("ot-confirm-with") modal: OtConfirmModal;
@HostListener("click")
requestConfirm() {
this.modal.confirm();
}
}
Angular 2
$element.on("click",
requestConfirm)
@Directive({
selector: "[ot-confirm-with]"
})
class OtConfirmWith {
@Input("ot-confirm-with") modal: OtConfirmModal;
@Output() confirm: EventEmitter = new EventEmitter();
@HostListener("click")
requestConfirm() {
this.modal.confirm();
}
}
Angular 2
@Directive({
selector: "[ot-confirm-with]"
})
class OtConfirmWith {
@Input("ot-confirm-with") modal: OtConfirmModal;
@Output() confirm: EventEmitter = new EventEmitter();
@HostListener("click")
requestConfirm() {
this.modal.confirm();
}
emitConfirmEvent() {
this.confirm.next();
}
Angular 2...
@Directive({
selector: "[ot-confirm-with]"
})
class OtConfirmWith {
@Input("ot-confirm-with") modal: OtConfirmModal;
@Output() confirm: EventEmitter = new EventEmitter();
@HostListener("click")
requestConfirm() {
this.modal.confirm(this.emitConfirmEvent.bind(this));
}
emitConfirmEvent() {
this.confirm.next();
}
Angular 2...
@Directive({ selector: "[ot-confirm-with]" })
class OtConfirmWith {
@Input("ot-confirm-with") modal: OtConfirmModal;
@Output() confirm: EventEmitter = new EventEmitter();
@HostListener("click")
requestConfirm() {
this.modal.confirm(this.emitConfirmEvent.bind(this));
}
emitConfirmEvent() {
this.confirm.next();
}
}
Angular 2
Thanks
OpenTable, Sara Rahimian,
Simon Attley, Guest Center Web team
Links
Creating Container Components talk
Custom Element Examples
Angular Examples
Photos
Gratisography & Unsplash
All photos public domain.
Thanks
OpenTable, Sara Rahimian,
Simon Attley, Guest Center Web team
Links
Creating Container Components talk
Custom Element Examples
Angular Examples
Photos
Gratisography & Unsplash
All 3rd party photos public domain.
OpenTable is hiring!
We’re hiring!
Visit our careers page at
opentable.com/careers/
We’re hiring!
Visit our careers page at
opentable.com/careers/
Ad

Recommended

Creating GUI container components in Angular and Web Components
Creating GUI container components in Angular and Web Components
Rachael L Moore
 
前端概述
前端概述
Ethan Zhang
 
jQuery from the very beginning
jQuery from the very beginning
Anis Ahmad
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012
Nicholas Zakas
 
jQuery PPT
jQuery PPT
Dominic Arrojado
 
Zf2 how arrays will save your project
Zf2 how arrays will save your project
Michelangelo van Dam
 
GWT integration with Vaadin
GWT integration with Vaadin
Peter Lehto
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
jQuery in 15 minutes
jQuery in 15 minutes
Simon Willison
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
velveeta_512
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
Shumpei Shiraishi
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
jQuery for Sharepoint Dev
jQuery for Sharepoint Dev
Zeddy Iskandar
 
Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014
Naresha K
 
Sane Async Patterns
Sane Async Patterns
TrevorBurnham
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLon
Fokke Zandbergen
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web components
psstoev
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can e big
Andy Peterson
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1
Paras Mendiratta
 
Yearning jQuery
Yearning jQuery
Remy Sharp
 
J query training
J query training
FIS - Fidelity Information Services
 
jQuery Features to Avoid
jQuery Features to Avoid
dmethvin
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101
Ted Kulp
 
Modules and injector
Modules and injector
Eyal Vardi
 
Protractor Training in Pune by QuickITDotnet
Protractor Training in Pune by QuickITDotnet
QuickITDotNet Training and Services
 
Unobtrusive javascript with jQuery
Unobtrusive javascript with jQuery
Angel Ruiz
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
Remy Sharp
 
Get AngularJS Started!
Get AngularJS Started!
Dzmitry Ivashutsin
 
Distributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component world
Rachael L Moore
 
Operations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS Developers
Rachael L Moore
 

More Related Content

What's hot (20)

jQuery in 15 minutes
jQuery in 15 minutes
Simon Willison
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
velveeta_512
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
Shumpei Shiraishi
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
jQuery for Sharepoint Dev
jQuery for Sharepoint Dev
Zeddy Iskandar
 
Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014
Naresha K
 
Sane Async Patterns
Sane Async Patterns
TrevorBurnham
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLon
Fokke Zandbergen
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web components
psstoev
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can e big
Andy Peterson
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1
Paras Mendiratta
 
Yearning jQuery
Yearning jQuery
Remy Sharp
 
J query training
J query training
FIS - Fidelity Information Services
 
jQuery Features to Avoid
jQuery Features to Avoid
dmethvin
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101
Ted Kulp
 
Modules and injector
Modules and injector
Eyal Vardi
 
Protractor Training in Pune by QuickITDotnet
Protractor Training in Pune by QuickITDotnet
QuickITDotNet Training and Services
 
Unobtrusive javascript with jQuery
Unobtrusive javascript with jQuery
Angel Ruiz
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
Remy Sharp
 
Get AngularJS Started!
Get AngularJS Started!
Dzmitry Ivashutsin
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
velveeta_512
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
jQuery for Sharepoint Dev
jQuery for Sharepoint Dev
Zeddy Iskandar
 
Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014
Naresha K
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLon
Fokke Zandbergen
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web components
psstoev
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can e big
Andy Peterson
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1
Paras Mendiratta
 
Yearning jQuery
Yearning jQuery
Remy Sharp
 
jQuery Features to Avoid
jQuery Features to Avoid
dmethvin
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101
Ted Kulp
 
Modules and injector
Modules and injector
Eyal Vardi
 
Unobtrusive javascript with jQuery
Unobtrusive javascript with jQuery
Angel Ruiz
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
Remy Sharp
 

Viewers also liked (14)

Distributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component world
Rachael L Moore
 
Operations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS Developers
Rachael L Moore
 
Microformats I: What & Why
Microformats I: What & Why
Rachael L Moore
 
Refresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End Story
Rachael L Moore
 
3a8 picture driven computing in assistive
3a8 picture driven computing in assistive
AEGIS-ACCESSIBLE Projects
 
Dependency injection
Dependency injection
Mindfire Solutions
 
FrontEnd platform based on AngularJS
FrontEnd platform based on AngularJS
Egor Miasnikov
 
Building Modern Web Apps with AngularJS
Building Modern Web Apps with AngularJS
Raveen Perera
 
AngularJS Beginners Workshop
AngularJS Beginners Workshop
Sathish VJ
 
Scope demystified - AngularJS
Scope demystified - AngularJS
Sumanth krishna
 
Angular 1.5 Components
Angular 1.5 Components
José Barbosa
 
Introduction to AngularJs
Introduction to AngularJs
murtazahaveliwala
 
Redefining your core product
Redefining your core product
InVision App
 
Open table pdf
Open table pdf
Stephen Woodruff
 
Distributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component world
Rachael L Moore
 
Operations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS Developers
Rachael L Moore
 
Microformats I: What & Why
Microformats I: What & Why
Rachael L Moore
 
Refresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End Story
Rachael L Moore
 
FrontEnd platform based on AngularJS
FrontEnd platform based on AngularJS
Egor Miasnikov
 
Building Modern Web Apps with AngularJS
Building Modern Web Apps with AngularJS
Raveen Perera
 
AngularJS Beginners Workshop
AngularJS Beginners Workshop
Sathish VJ
 
Scope demystified - AngularJS
Scope demystified - AngularJS
Sumanth krishna
 
Angular 1.5 Components
Angular 1.5 Components
José Barbosa
 
Redefining your core product
Redefining your core product
InVision App
 
Ad

Similar to Creating GUI Component APIs in Angular and Web Components (20)

Vaadin Components @ Angular U
Vaadin Components @ Angular U
Joonas Lehtinen
 
html5
html5
NebberCracker01
 
Introduccion a HTML5
Introduccion a HTML5
Pablo Garaizar
 
jQuery
jQuery
Vishwa Mohan
 
Alfresco Forms Service Deep Dive
Alfresco Forms Service Deep Dive
Alfresco Software
 
the next web now
the next web now
zulin Gu
 
Jquery tutorial
Jquery tutorial
Bui Kiet
 
JavaScript - Chapter 12 - Document Object Model
JavaScript - Chapter 12 - Document Object Model
WebStackAcademy
 
Basics of Java Script (JS)
Basics of Java Script (JS)
Ajay Khatri
 
DOM Quick Overview
DOM Quick Overview
Signure Technologies
 
Sahana Eden - Introduction to the Code
Sahana Eden - Introduction to the Code
AidIQ
 
Html Guide
Html Guide
Jspider - Noida
 
java ee 6 Petcatalog
java ee 6 Petcatalog
Carol McDonald
 
Html5 and web technology update
Html5 and web technology update
Doug Domeny
 
The Ring programming language version 1.5.2 book - Part 44 of 181
The Ring programming language version 1.5.2 book - Part 44 of 181
Mahmoud Samir Fayed
 
RIA and Ajax
RIA and Ajax
Schubert Gomes
 
Wt unit 5
Wt unit 5
team11vgnt
 
Client-side JavaScript
Client-side JavaScript
Lilia Sfaxi
 
Lerman Vvs14 Ef Tips And Tricks
Lerman Vvs14 Ef Tips And Tricks
Julie Lerman
 
Wt unit 2 ppts client side technology
Wt unit 2 ppts client side technology
PUNE VIDYARTHI GRIHA'S COLLEGE OF ENGINEERING, NASHIK
 
Vaadin Components @ Angular U
Vaadin Components @ Angular U
Joonas Lehtinen
 
Alfresco Forms Service Deep Dive
Alfresco Forms Service Deep Dive
Alfresco Software
 
the next web now
the next web now
zulin Gu
 
Jquery tutorial
Jquery tutorial
Bui Kiet
 
JavaScript - Chapter 12 - Document Object Model
JavaScript - Chapter 12 - Document Object Model
WebStackAcademy
 
Basics of Java Script (JS)
Basics of Java Script (JS)
Ajay Khatri
 
Sahana Eden - Introduction to the Code
Sahana Eden - Introduction to the Code
AidIQ
 
Html5 and web technology update
Html5 and web technology update
Doug Domeny
 
The Ring programming language version 1.5.2 book - Part 44 of 181
The Ring programming language version 1.5.2 book - Part 44 of 181
Mahmoud Samir Fayed
 
Client-side JavaScript
Client-side JavaScript
Lilia Sfaxi
 
Lerman Vvs14 Ef Tips And Tricks
Lerman Vvs14 Ef Tips And Tricks
Julie Lerman
 
Ad

Recently uploaded (20)

EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
WebdriverIO & JavaScript: The Perfect Duo for Web Automation
WebdriverIO & JavaScript: The Perfect Duo for Web Automation
digitaljignect
 
cnc-processing-centers-centateq-p-110-en.pdf
cnc-processing-centers-centateq-p-110-en.pdf
AmirStern2
 
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Scaling in space and time with Temporal", Andriy Lupa.pdf
Fwdays
 
The Future of Technology: 2025-2125 by Saikat Basu.pdf
The Future of Technology: 2025-2125 by Saikat Basu.pdf
Saikat Basu
 
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
caoyixuan2019
 
Connecting Data and Intelligence: The Role of FME in Machine Learning
Connecting Data and Intelligence: The Role of FME in Machine Learning
Safe Software
 
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
UserCon Belgium: Honey, VMware increased my bill
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
10 Key Challenges for AI within the EU Data Protection Framework.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Priyanka Aash
 
Python Conference Singapore - 19 Jun 2025
Python Conference Singapore - 19 Jun 2025
ninefyi
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
"Database isolation: how we deal with hundreds of direct connections to the d...
"Database isolation: how we deal with hundreds of direct connections to the d...
Fwdays
 
OpenPOWER Foundation & Open-Source Core Innovations
OpenPOWER Foundation & Open-Source Core Innovations
IBM
 
2025_06_18 - OpenMetadata Community Meeting.pdf
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
You are not excused! How to avoid security blind spots on the way to production
You are not excused! How to avoid security blind spots on the way to production
Michele Leroux Bustamante
 
The Future of Product Management in AI ERA.pdf
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
From Manual to Auto Searching- FME in the Driver's Seat
From Manual to Auto Searching- FME in the Driver's Seat
Safe Software
 
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
janeliewang985
 
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
WebdriverIO & JavaScript: The Perfect Duo for Web Automation
WebdriverIO & JavaScript: The Perfect Duo for Web Automation
digitaljignect
 
cnc-processing-centers-centateq-p-110-en.pdf
cnc-processing-centers-centateq-p-110-en.pdf
AmirStern2
 
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Scaling in space and time with Temporal", Andriy Lupa.pdf
Fwdays
 
The Future of Technology: 2025-2125 by Saikat Basu.pdf
The Future of Technology: 2025-2125 by Saikat Basu.pdf
Saikat Basu
 
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
caoyixuan2019
 
Connecting Data and Intelligence: The Role of FME in Machine Learning
Connecting Data and Intelligence: The Role of FME in Machine Learning
Safe Software
 
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
UserCon Belgium: Honey, VMware increased my bill
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
10 Key Challenges for AI within the EU Data Protection Framework.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Priyanka Aash
 
Python Conference Singapore - 19 Jun 2025
Python Conference Singapore - 19 Jun 2025
ninefyi
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
"Database isolation: how we deal with hundreds of direct connections to the d...
"Database isolation: how we deal with hundreds of direct connections to the d...
Fwdays
 
OpenPOWER Foundation & Open-Source Core Innovations
OpenPOWER Foundation & Open-Source Core Innovations
IBM
 
2025_06_18 - OpenMetadata Community Meeting.pdf
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
You are not excused! How to avoid security blind spots on the way to production
You are not excused! How to avoid security blind spots on the way to production
Michele Leroux Bustamante
 
The Future of Product Management in AI ERA.pdf
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
From Manual to Auto Searching- FME in the Driver's Seat
From Manual to Auto Searching- FME in the Driver's Seat
Safe Software
 
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
janeliewang985
 

Creating GUI Component APIs in Angular and Web Components