SlideShare a Scribd company logo
1 of 179
Download to read offline
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
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/

More Related Content

What's hot

Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgetsvelveeta_512
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionPaul Irish
 
jQuery for Sharepoint Dev
jQuery for Sharepoint DevjQuery for Sharepoint Dev
jQuery for Sharepoint DevZeddy Iskandar
 
Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014Naresha K
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonAlloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonFokke Zandbergen
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentsPolymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentspsstoev
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e bigAndy Peterson
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1Angular JS2 Training Session #1
Angular JS2 Training Session #1Paras Mendiratta
 
Yearning jQuery
Yearning jQueryYearning jQuery
Yearning jQueryRemy Sharp
 
jQuery Features to Avoid
jQuery Features to AvoidjQuery Features to Avoid
jQuery Features to Avoiddmethvin
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Ted Kulp
 
Modules and injector
Modules and injectorModules and injector
Modules and injectorEyal Vardi
 
Unobtrusive javascript with jQuery
Unobtrusive javascript with jQueryUnobtrusive javascript with jQuery
Unobtrusive javascript with jQueryAngel Ruiz
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Remy Sharp
 

What's hot (20)

jQuery in 15 minutes
jQuery in 15 minutesjQuery in 15 minutes
jQuery in 15 minutes
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fallHtml5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
 
jQuery for Sharepoint Dev
jQuery for Sharepoint DevjQuery for Sharepoint Dev
jQuery for Sharepoint Dev
 
Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonAlloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLon
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentsPolymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web components
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1Angular JS2 Training Session #1
Angular JS2 Training Session #1
 
Yearning jQuery
Yearning jQueryYearning jQuery
Yearning jQuery
 
J query training
J query trainingJ query training
J query training
 
jQuery Features to Avoid
jQuery Features to AvoidjQuery Features to Avoid
jQuery Features to Avoid
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101
 
Modules and injector
Modules and injectorModules and injector
Modules and injector
 
Protractor Training in Pune by QuickITDotnet
Protractor Training in Pune by QuickITDotnet Protractor Training in Pune by QuickITDotnet
Protractor Training in Pune by QuickITDotnet
 
Unobtrusive javascript with jQuery
Unobtrusive javascript with jQueryUnobtrusive javascript with jQuery
Unobtrusive javascript with jQuery
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
 

Viewers also liked

Distributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component worldDistributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component worldRachael L Moore
 
Operations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS DevelopersOperations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS DevelopersRachael L Moore
 
Microformats I: What & Why
Microformats I: What & WhyMicroformats I: What & Why
Microformats I: What & WhyRachael L Moore
 
Refresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End StoryRefresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End StoryRachael L Moore
 
FrontEnd platform based on AngularJS
FrontEnd platform based on AngularJSFrontEnd platform based on AngularJS
FrontEnd platform based on AngularJSEgor Miasnikov
 
Building Modern Web Apps with AngularJS
Building Modern Web Apps with AngularJSBuilding Modern Web Apps with AngularJS
Building Modern Web Apps with AngularJSRaveen Perera
 
AngularJS Beginners Workshop
AngularJS Beginners WorkshopAngularJS Beginners Workshop
AngularJS Beginners WorkshopSathish VJ
 
Scope demystified - AngularJS
Scope demystified - AngularJSScope demystified - AngularJS
Scope demystified - AngularJSSumanth krishna
 
Angular 1.5 Components
Angular 1.5 ComponentsAngular 1.5 Components
Angular 1.5 ComponentsJosé Barbosa
 
Redefining your core product
Redefining your core productRedefining your core product
Redefining your core productInVision App
 

Viewers also liked (14)

Distributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component worldDistributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component world
 
Operations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS DevelopersOperations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS Developers
 
Microformats I: What & Why
Microformats I: What & WhyMicroformats I: What & Why
Microformats I: What & Why
 
Refresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End StoryRefresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End Story
 
3a8 picture driven computing in assistive
3a8 picture driven computing in assistive3a8 picture driven computing in assistive
3a8 picture driven computing in assistive
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
FrontEnd platform based on AngularJS
FrontEnd platform based on AngularJSFrontEnd platform based on AngularJS
FrontEnd platform based on AngularJS
 
Building Modern Web Apps with AngularJS
Building Modern Web Apps with AngularJSBuilding Modern Web Apps with AngularJS
Building Modern Web Apps with AngularJS
 
AngularJS Beginners Workshop
AngularJS Beginners WorkshopAngularJS Beginners Workshop
AngularJS Beginners Workshop
 
Scope demystified - AngularJS
Scope demystified - AngularJSScope demystified - AngularJS
Scope demystified - AngularJS
 
Angular 1.5 Components
Angular 1.5 ComponentsAngular 1.5 Components
Angular 1.5 Components
 
Introduction to AngularJs
Introduction to AngularJsIntroduction to AngularJs
Introduction to AngularJs
 
Redefining your core product
Redefining your core productRedefining your core product
Redefining your core product
 
Open table pdf
Open table pdfOpen table pdf
Open table pdf
 

Similar to Creating GUI Component APIs in Angular and Web Components

Vaadin Components @ Angular U
Vaadin Components @ Angular UVaadin Components @ Angular U
Vaadin Components @ Angular UJoonas Lehtinen
 
Alfresco Forms Service Deep Dive
Alfresco Forms Service Deep DiveAlfresco Forms Service Deep Dive
Alfresco Forms Service Deep DiveAlfresco Software
 
the next web now
the next web nowthe next web now
the next web nowzulin Gu
 
Jquery tutorial
Jquery tutorialJquery tutorial
Jquery tutorialBui Kiet
 
JavaScript - Chapter 12 - Document Object Model
  JavaScript - Chapter 12 - Document Object Model  JavaScript - Chapter 12 - Document Object Model
JavaScript - Chapter 12 - Document Object ModelWebStackAcademy
 
Basics of Java Script (JS)
Basics of Java Script (JS)Basics of Java Script (JS)
Basics of Java Script (JS)Ajay Khatri
 
Sahana Eden - Introduction to the Code
Sahana Eden - Introduction to the CodeSahana Eden - Introduction to the Code
Sahana Eden - Introduction to the CodeAidIQ
 
Html5 and web technology update
Html5 and web technology updateHtml5 and web technology update
Html5 and web technology updateDoug 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 181The Ring programming language version 1.5.2 book - Part 44 of 181
The Ring programming language version 1.5.2 book - Part 44 of 181Mahmoud Samir Fayed
 
Client-side JavaScript
Client-side JavaScriptClient-side JavaScript
Client-side JavaScriptLilia Sfaxi
 
Lerman Vvs14 Ef Tips And Tricks
Lerman Vvs14  Ef Tips And TricksLerman Vvs14  Ef Tips And Tricks
Lerman Vvs14 Ef Tips And TricksJulie Lerman
 

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

Vaadin Components @ Angular U
Vaadin Components @ Angular UVaadin Components @ Angular U
Vaadin Components @ Angular U
 
Introduccion a HTML5
Introduccion a HTML5Introduccion a HTML5
Introduccion a HTML5
 
html5
html5html5
html5
 
jQuery
jQueryjQuery
jQuery
 
Alfresco Forms Service Deep Dive
Alfresco Forms Service Deep DiveAlfresco Forms Service Deep Dive
Alfresco Forms Service Deep Dive
 
the next web now
the next web nowthe next web now
the next web now
 
Jquery tutorial
Jquery tutorialJquery tutorial
Jquery tutorial
 
JavaScript - Chapter 12 - Document Object Model
  JavaScript - Chapter 12 - Document Object Model  JavaScript - Chapter 12 - Document Object Model
JavaScript - Chapter 12 - Document Object Model
 
Basics of Java Script (JS)
Basics of Java Script (JS)Basics of Java Script (JS)
Basics of Java Script (JS)
 
DOM Quick Overview
DOM Quick OverviewDOM Quick Overview
DOM Quick Overview
 
Sahana Eden - Introduction to the Code
Sahana Eden - Introduction to the CodeSahana Eden - Introduction to the Code
Sahana Eden - Introduction to the Code
 
Html Guide
Html GuideHtml Guide
Html Guide
 
java ee 6 Petcatalog
java ee 6 Petcatalogjava ee 6 Petcatalog
java ee 6 Petcatalog
 
Html5 and web technology update
Html5 and web technology updateHtml5 and web technology update
Html5 and web technology update
 
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 181The 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
 
RIA and Ajax
RIA and AjaxRIA and Ajax
RIA and Ajax
 
Wt unit 5
Wt unit 5Wt unit 5
Wt unit 5
 
Client-side JavaScript
Client-side JavaScriptClient-side JavaScript
Client-side JavaScript
 
Lerman Vvs14 Ef Tips And Tricks
Lerman Vvs14  Ef Tips And TricksLerman Vvs14  Ef Tips And Tricks
Lerman Vvs14 Ef Tips And Tricks
 
Wt unit 2 ppts client sied technology
Wt unit 2 ppts client sied technologyWt unit 2 ppts client sied technology
Wt unit 2 ppts client sied technology
 

Recently uploaded

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 

Recently uploaded (20)

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 

Creating GUI Component APIs in Angular and Web Components