SlideShare uma empresa Scribd logo
© 2018 ServiceNow All Rights Reserved
Making Service Portal Widgets
Work Together
Travis Toulson
Sr. Architect
GlideFast Consulting
© 2016 ServiceNow All Rights Reserved 2Confidential
2
#Know18
© 2018 ServiceNow All Rights Reserved
Widgets are volatile,
self-obsessed, and
don’t play well with
others
Problem
© 2016 ServiceNow All Rights Reserved 3Confidential
3
#Know18
© 2018 ServiceNow All Rights Reserved
ng-app
ng-controller
container
row
column
rectangle
widget
The Design
Powerful widgets simplify
everything else
© 2016 ServiceNow All Rights Reserved 4Confidential
4
#Know18
© 2018 ServiceNow All Rights Reserved
BUT…
© 2016 ServiceNow All Rights Reserved 5Confidential
5
#Know18
© 2018 ServiceNow All Rights Reserved
© 2016 ServiceNow All Rights Reserved 6Confidential
6
#Know18
© 2018 ServiceNow All Rights Reserved
Massive
Widgets
Repetitive
Widgets
VS
© 2016 ServiceNow All Rights Reserved 7Confidential
7
#Know18
© 2018 ServiceNow All Rights Reserved
Embed widgets to
compose complex
behaviors
#1
© 2016 ServiceNow All Rights Reserved 8Confidential
8
#Know18
© 2018 ServiceNow All Rights Reserved
ç
Data Table Widget
- 7 Different Behaviors
- Over 300 lines of client
code
- Over 150 lines of server
code
© 2016 ServiceNow All Rights Reserved 9Confidential
9
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 10Confidential
10
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 11Confidential
11
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 12Confidential
12
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 13Confidential
13
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 14Confidential
14
#Know18
© 2018 ServiceNow All Rights Reserved
<div>
<sp-widget widget="data.filterBreadcrumbs">
</sp-widget>
</div>
var breadcrumbWidgetParams = {
table: data.table,
query: data.filter,
enable_filter: data.enable_filter
};
data.filterBreadcrumbs = $sp.getWidget(
'widget-filter-breadcrumbs',
breadcrumbWidgetParams);
HTML
Server Script
© 2016 ServiceNow All Rights Reserved 15Confidential
15
#Know18
© 2018 ServiceNow All Rights Reserved
A “child scope” (prototypically)
inherits properties from its
“parent scope”
“
- AngularJS Developer Guide
© 2016 ServiceNow All Rights Reserved 16Confidential
16
#Know18
© 2018 ServiceNow All Rights Reserved
<a style="display: inline;" href>{{page.title}}</a>
Data Table Widget
HTML Template
© 2016 ServiceNow All Rights Reserved 17Confidential
17
#Know18
© 2018 ServiceNow All Rights Reserved
ng-app
ng-controller
container
row
column
rectangle
widget
{{page.title}}
Data Table Widget
doesn’t have a page
object?!?!
© 2016 ServiceNow All Rights Reserved 18Confidential
18
#Know18
© 2018 ServiceNow All Rights Reserved
Child Widgets inherit
functions and data
from their Parent
Widgets
© 2016 ServiceNow All Rights Reserved 19Confidential
19
#Know18
© 2018 ServiceNow All Rights Reserved
Structure application
models with Angular
Services
#2
© 2016 ServiceNow All Rights Reserved 20Confidential
20
#Know18
© 2018 ServiceNow All Rights Reserved
You can use services to organize
and share code across your app
“
- AngularJS Developer Guide
© 2016 ServiceNow All Rights Reserved 21Confidential
21
#Know18
© 2018 ServiceNow All Rights Reserved
1. Create the Angular Provider
2. Add it to the Widget’s Angular
Provider Related List
3. Inject the dependency into the
Client Script
Wire up a Service
© 2016 ServiceNow All Rights Reserved 22Confidential
22
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 23Confidential
23
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 24Confidential
24
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 25Confidential
25
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 26Confidential
26
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 27Confidential
27
#Know18
© 2018 ServiceNow All Rights Reserved
function($http) {
var incidents = [];
function reload() {
$http.get(‘/api/now/table/incident’)
.then(function(res) { incidents = res.result; });
}
function get() {
return incidents;
}
return {
‘reload’: reload,
‘get’: get
};
}
Service
Type: Service
Name: incidentService
© 2016 ServiceNow All Rights Reserved 28Confidential
28
#Know18
© 2018 ServiceNow All Rights Reserved
function (incidentService) {
var c = this;
incidentService.reload();
c.reload = function() {
incidentService.reload();
}
c.getIncidents = function() {
return incidentService.get();
}
}
Client Script
© 2016 ServiceNow All Rights Reserved 29Confidential
29
#Know18
© 2018 ServiceNow All Rights Reserved
function (incidentService) {
var c = this;
incidentService.reload();
c.reload = function() {
incidentService.reload();
}
c.getIncidents = function() {
return incidentService.get();
}
}
Client Script
© 2016 ServiceNow All Rights Reserved 30Confidential
30
#Know18
© 2018 ServiceNow All Rights Reserved
function (incidentService) {
var c = this;
incidentService.reload();
c.reload = function() {
incidentService.reload();
}
c.getIncidents = function() {
return incidentService.get();
}
}
Client Script
© 2016 ServiceNow All Rights Reserved 31Confidential
31
#Know18
© 2018 ServiceNow All Rights Reserved
function (incidentService) {
var c = this;
incidentService.reload();
c.reload = function() {
incidentService.reload();
}
c.getIncidents = function() {
return incidentService.get();
}
}
Client Script
© 2016 ServiceNow All Rights Reserved 32Confidential
32
#Know18
© 2018 ServiceNow All Rights Reserved
function (incidentService) {
var c = this;
incidentService.reload();
c.reload = function() {
incidentService.reload();
}
c.getIncidents = function() {
return incidentService.get();
}
}
Client Script
© 2016 ServiceNow All Rights Reserved 33Confidential
33
#Know18
© 2018 ServiceNow All Rights Reserved
<div ng-repeat=“inc in c.getIncidents()”>
<!-- Incident Template Here -->
</div>
Digest Loop
HTML Template
© 2016 ServiceNow All Rights Reserved 34Confidential
34
#Know18
© 2018 ServiceNow All Rights Reserved
Use Angular Events as
a last resort
#3
© 2016 ServiceNow All Rights Reserved 35Confidential
35
#Know18
© 2018 ServiceNow All Rights Reserved
Insanity Warning: scope depth-
first traversal. Yes, this code is a
bit crazy, but it works and we
have tests to prove it
“
- Line 1417, rootScope.js AngularJS Source Code
© 2016 ServiceNow All Rights Reserved 36Confidential
36
#Know18
© 2018 ServiceNow All Rights Reserved
ng-app
ng-controller
container
row
column
rectangle
widget
Event Propagation
$rootScope
$scope
$broadcast
$emit
$on
© 2016 ServiceNow All Rights Reserved 37Confidential
37
#Know18
© 2018 ServiceNow All Rights Reserved
But given that it’s a
stupid a** decision,
I’ve elected to ignore
it
© 2016 ServiceNow All Rights Reserved 38Confidential
38
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 39Confidential
39
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 40Confidential
40
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 41Confidential
41
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 42Confidential
42
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 43Confidential
43
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 44Confidential
44
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 45Confidential
45
#Know18
© 2018 ServiceNow All Rights Reserved
function ($scope) {
$scope.$on(‘incident.changed’,
function(event, data) {
// Do something!
});
}
function ($rootScope) {
$rootScope.$broadcast(‘incident.changed’, {});
}
Widget 2
Client Script
Widget 1
Client Script
© 2016 ServiceNow All Rights Reserved 46Confidential
46
#Know18
© 2018 ServiceNow All Rights Reserved
Embed
widgets to
compose
complex
behaviors
#1
Structure
application
models with
Angular
Services
#2
Use Angular
Events as a
last resort
#3
© 2016 ServiceNow All Rights Reserved 47Confidential
47
#Know18
© 2018 ServiceNow All Rights Reserved
© 2016 ServiceNow All Rights Reserved 48Confidential
48
#Know18
© 2018 ServiceNow All Rights Reserved
Travis Toulson
Sr. Architect
GlideFast Consulting
travis.toulson@glidefast.com
Thank You

Mais conteúdo relacionado

Semelhante a Making Service Portal Widgets Work Together

Chris Wilson: Progressive Web Apps
Chris Wilson: Progressive Web AppsChris Wilson: Progressive Web Apps
Chris Wilson: Progressive Web Apps
Danielle A Vincent
 
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdfMonetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Amazon Web Services
 
GlueCon 2016 - Threading in JavaScript
GlueCon 2016 - Threading in JavaScriptGlueCon 2016 - Threading in JavaScript
GlueCon 2016 - Threading in JavaScript
Jonathan Baker
 
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with FargateDEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
Amazon Web Services
 
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
Amazon Web Services
 
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
Amazon Web Services
 
Criteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) MeetupCriteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) Meetup
Ibrahim Abubakari
 
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
Amazon Web Services
 
How to implement payment gateway integration for non-credit card on Magento2
How to implement payment gateway integration for non-credit card on Magento2How to implement payment gateway integration for non-credit card on Magento2
How to implement payment gateway integration for non-credit card on Magento2
Hirokazu Nishi
 
The Future of Progressive Web Apps - Google for Indonesia
The Future of Progressive Web Apps - Google for IndonesiaThe Future of Progressive Web Apps - Google for Indonesia
The Future of Progressive Web Apps - Google for Indonesia
Robert Nyman
 
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
InfluxData
 
DataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJSDataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJS
DataStax Academy
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
Ignacio Martín
 
Developing Business Blockchain Applications on Hyperledger
Developing Business  Blockchain Applications on Hyperledger Developing Business  Blockchain Applications on Hyperledger
Developing Business Blockchain Applications on Hyperledger
IMC Institute
 
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
Amazon Web Services
 
Building web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend ExpressiveBuilding web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend Expressive
Zend by Rogue Wave Software
 
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
DevOps.com
 
twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC#46 一探 C# 11 與 .NET 7 的神奇twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC
 
Urban Airship and Android Integration for Push Notification and In-App Notifi...
Urban Airship and Android Integration for Push Notification and In-App Notifi...Urban Airship and Android Integration for Push Notification and In-App Notifi...
Urban Airship and Android Integration for Push Notification and In-App Notifi...
Zeeshan Rahman
 
Urban Airship & Android Application Integration Document
Urban Airship & Android Application Integration DocumentUrban Airship & Android Application Integration Document
Urban Airship & Android Application Integration Document
mobi fly
 

Semelhante a Making Service Portal Widgets Work Together (20)

Chris Wilson: Progressive Web Apps
Chris Wilson: Progressive Web AppsChris Wilson: Progressive Web Apps
Chris Wilson: Progressive Web Apps
 
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdfMonetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
 
GlueCon 2016 - Threading in JavaScript
GlueCon 2016 - Threading in JavaScriptGlueCon 2016 - Threading in JavaScript
GlueCon 2016 - Threading in JavaScript
 
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with FargateDEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
DEM07 Best Practices for Monitoring Amazon ECS Containers Launched with Fargate
 
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
Executing a Large Scale Migration to AWS (ENT337-R2) - AWS re:Invent 2018
 
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
Best Practices for Scalable Monitoring (ENT310-S) - AWS re:Invent 2018
 
Criteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) MeetupCriteo Infrastructure (Platform) Meetup
Criteo Infrastructure (Platform) Meetup
 
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
Engage Users in Real-Time through Event-Based Messaging (MOB322-R1) - AWS re:...
 
How to implement payment gateway integration for non-credit card on Magento2
How to implement payment gateway integration for non-credit card on Magento2How to implement payment gateway integration for non-credit card on Magento2
How to implement payment gateway integration for non-credit card on Magento2
 
The Future of Progressive Web Apps - Google for Indonesia
The Future of Progressive Web Apps - Google for IndonesiaThe Future of Progressive Web Apps - Google for Indonesia
The Future of Progressive Web Apps - Google for Indonesia
 
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
InfluxDB 101 – Concepts and Architecture by Michael DeSa, Software Engineer |...
 
DataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJSDataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJS
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
 
Developing Business Blockchain Applications on Hyperledger
Developing Business  Blockchain Applications on Hyperledger Developing Business  Blockchain Applications on Hyperledger
Developing Business Blockchain Applications on Hyperledger
 
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
AWS, I Choose You: Pokemon's Battle against the Bots (SEC402-R1) - AWS re:Inv...
 
Building web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend ExpressiveBuilding web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend Expressive
 
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
Learn How to Use a Time Series Platform to Monitor All Aspects of Your Kubern...
 
twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC#46 一探 C# 11 與 .NET 7 的神奇twMVC#46 一探 C# 11 與 .NET 7 的神奇
twMVC#46 一探 C# 11 與 .NET 7 的神奇
 
Urban Airship and Android Integration for Push Notification and In-App Notifi...
Urban Airship and Android Integration for Push Notification and In-App Notifi...Urban Airship and Android Integration for Push Notification and In-App Notifi...
Urban Airship and Android Integration for Push Notification and In-App Notifi...
 
Urban Airship & Android Application Integration Document
Urban Airship & Android Application Integration DocumentUrban Airship & Android Application Integration Document
Urban Airship & Android Application Integration Document
 

Último

Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
Daiki Mogmet Ito
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
Zilliz
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
Tatiana Kojar
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
Edge AI and Vision Alliance
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
IndexBug
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
Zilliz
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
Webinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data WarehouseWebinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data Warehouse
Federico Razzoli
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
Tomaz Bratanic
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 

Último (20)

Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
Webinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data WarehouseWebinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data Warehouse
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 

Making Service Portal Widgets Work Together

  • 1. © 2018 ServiceNow All Rights Reserved Making Service Portal Widgets Work Together Travis Toulson Sr. Architect GlideFast Consulting
  • 2. © 2016 ServiceNow All Rights Reserved 2Confidential 2 #Know18 © 2018 ServiceNow All Rights Reserved Widgets are volatile, self-obsessed, and don’t play well with others Problem
  • 3. © 2016 ServiceNow All Rights Reserved 3Confidential 3 #Know18 © 2018 ServiceNow All Rights Reserved ng-app ng-controller container row column rectangle widget The Design Powerful widgets simplify everything else
  • 4. © 2016 ServiceNow All Rights Reserved 4Confidential 4 #Know18 © 2018 ServiceNow All Rights Reserved BUT…
  • 5. © 2016 ServiceNow All Rights Reserved 5Confidential 5 #Know18 © 2018 ServiceNow All Rights Reserved
  • 6. © 2016 ServiceNow All Rights Reserved 6Confidential 6 #Know18 © 2018 ServiceNow All Rights Reserved Massive Widgets Repetitive Widgets VS
  • 7. © 2016 ServiceNow All Rights Reserved 7Confidential 7 #Know18 © 2018 ServiceNow All Rights Reserved Embed widgets to compose complex behaviors #1
  • 8. © 2016 ServiceNow All Rights Reserved 8Confidential 8 #Know18 © 2018 ServiceNow All Rights Reserved ç Data Table Widget - 7 Different Behaviors - Over 300 lines of client code - Over 150 lines of server code
  • 9. © 2016 ServiceNow All Rights Reserved 9Confidential 9 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 10. © 2016 ServiceNow All Rights Reserved 10Confidential 10 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 11. © 2016 ServiceNow All Rights Reserved 11Confidential 11 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 12. © 2016 ServiceNow All Rights Reserved 12Confidential 12 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 13. © 2016 ServiceNow All Rights Reserved 13Confidential 13 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 14. © 2016 ServiceNow All Rights Reserved 14Confidential 14 #Know18 © 2018 ServiceNow All Rights Reserved <div> <sp-widget widget="data.filterBreadcrumbs"> </sp-widget> </div> var breadcrumbWidgetParams = { table: data.table, query: data.filter, enable_filter: data.enable_filter }; data.filterBreadcrumbs = $sp.getWidget( 'widget-filter-breadcrumbs', breadcrumbWidgetParams); HTML Server Script
  • 15. © 2016 ServiceNow All Rights Reserved 15Confidential 15 #Know18 © 2018 ServiceNow All Rights Reserved A “child scope” (prototypically) inherits properties from its “parent scope” “ - AngularJS Developer Guide
  • 16. © 2016 ServiceNow All Rights Reserved 16Confidential 16 #Know18 © 2018 ServiceNow All Rights Reserved <a style="display: inline;" href>{{page.title}}</a> Data Table Widget HTML Template
  • 17. © 2016 ServiceNow All Rights Reserved 17Confidential 17 #Know18 © 2018 ServiceNow All Rights Reserved ng-app ng-controller container row column rectangle widget {{page.title}} Data Table Widget doesn’t have a page object?!?!
  • 18. © 2016 ServiceNow All Rights Reserved 18Confidential 18 #Know18 © 2018 ServiceNow All Rights Reserved Child Widgets inherit functions and data from their Parent Widgets
  • 19. © 2016 ServiceNow All Rights Reserved 19Confidential 19 #Know18 © 2018 ServiceNow All Rights Reserved Structure application models with Angular Services #2
  • 20. © 2016 ServiceNow All Rights Reserved 20Confidential 20 #Know18 © 2018 ServiceNow All Rights Reserved You can use services to organize and share code across your app “ - AngularJS Developer Guide
  • 21. © 2016 ServiceNow All Rights Reserved 21Confidential 21 #Know18 © 2018 ServiceNow All Rights Reserved 1. Create the Angular Provider 2. Add it to the Widget’s Angular Provider Related List 3. Inject the dependency into the Client Script Wire up a Service
  • 22. © 2016 ServiceNow All Rights Reserved 22Confidential 22 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 23. © 2016 ServiceNow All Rights Reserved 23Confidential 23 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 24. © 2016 ServiceNow All Rights Reserved 24Confidential 24 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 25. © 2016 ServiceNow All Rights Reserved 25Confidential 25 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 26. © 2016 ServiceNow All Rights Reserved 26Confidential 26 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 27. © 2016 ServiceNow All Rights Reserved 27Confidential 27 #Know18 © 2018 ServiceNow All Rights Reserved function($http) { var incidents = []; function reload() { $http.get(‘/api/now/table/incident’) .then(function(res) { incidents = res.result; }); } function get() { return incidents; } return { ‘reload’: reload, ‘get’: get }; } Service Type: Service Name: incidentService
  • 28. © 2016 ServiceNow All Rights Reserved 28Confidential 28 #Know18 © 2018 ServiceNow All Rights Reserved function (incidentService) { var c = this; incidentService.reload(); c.reload = function() { incidentService.reload(); } c.getIncidents = function() { return incidentService.get(); } } Client Script
  • 29. © 2016 ServiceNow All Rights Reserved 29Confidential 29 #Know18 © 2018 ServiceNow All Rights Reserved function (incidentService) { var c = this; incidentService.reload(); c.reload = function() { incidentService.reload(); } c.getIncidents = function() { return incidentService.get(); } } Client Script
  • 30. © 2016 ServiceNow All Rights Reserved 30Confidential 30 #Know18 © 2018 ServiceNow All Rights Reserved function (incidentService) { var c = this; incidentService.reload(); c.reload = function() { incidentService.reload(); } c.getIncidents = function() { return incidentService.get(); } } Client Script
  • 31. © 2016 ServiceNow All Rights Reserved 31Confidential 31 #Know18 © 2018 ServiceNow All Rights Reserved function (incidentService) { var c = this; incidentService.reload(); c.reload = function() { incidentService.reload(); } c.getIncidents = function() { return incidentService.get(); } } Client Script
  • 32. © 2016 ServiceNow All Rights Reserved 32Confidential 32 #Know18 © 2018 ServiceNow All Rights Reserved function (incidentService) { var c = this; incidentService.reload(); c.reload = function() { incidentService.reload(); } c.getIncidents = function() { return incidentService.get(); } } Client Script
  • 33. © 2016 ServiceNow All Rights Reserved 33Confidential 33 #Know18 © 2018 ServiceNow All Rights Reserved <div ng-repeat=“inc in c.getIncidents()”> <!-- Incident Template Here --> </div> Digest Loop HTML Template
  • 34. © 2016 ServiceNow All Rights Reserved 34Confidential 34 #Know18 © 2018 ServiceNow All Rights Reserved Use Angular Events as a last resort #3
  • 35. © 2016 ServiceNow All Rights Reserved 35Confidential 35 #Know18 © 2018 ServiceNow All Rights Reserved Insanity Warning: scope depth- first traversal. Yes, this code is a bit crazy, but it works and we have tests to prove it “ - Line 1417, rootScope.js AngularJS Source Code
  • 36. © 2016 ServiceNow All Rights Reserved 36Confidential 36 #Know18 © 2018 ServiceNow All Rights Reserved ng-app ng-controller container row column rectangle widget Event Propagation $rootScope $scope $broadcast $emit $on
  • 37. © 2016 ServiceNow All Rights Reserved 37Confidential 37 #Know18 © 2018 ServiceNow All Rights Reserved But given that it’s a stupid a** decision, I’ve elected to ignore it
  • 38. © 2016 ServiceNow All Rights Reserved 38Confidential 38 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 39. © 2016 ServiceNow All Rights Reserved 39Confidential 39 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 40. © 2016 ServiceNow All Rights Reserved 40Confidential 40 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 41. © 2016 ServiceNow All Rights Reserved 41Confidential 41 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 42. © 2016 ServiceNow All Rights Reserved 42Confidential 42 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 43. © 2016 ServiceNow All Rights Reserved 43Confidential 43 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 44. © 2016 ServiceNow All Rights Reserved 44Confidential 44 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 45. © 2016 ServiceNow All Rights Reserved 45Confidential 45 #Know18 © 2018 ServiceNow All Rights Reserved function ($scope) { $scope.$on(‘incident.changed’, function(event, data) { // Do something! }); } function ($rootScope) { $rootScope.$broadcast(‘incident.changed’, {}); } Widget 2 Client Script Widget 1 Client Script
  • 46. © 2016 ServiceNow All Rights Reserved 46Confidential 46 #Know18 © 2018 ServiceNow All Rights Reserved Embed widgets to compose complex behaviors #1 Structure application models with Angular Services #2 Use Angular Events as a last resort #3
  • 47. © 2016 ServiceNow All Rights Reserved 47Confidential 47 #Know18 © 2018 ServiceNow All Rights Reserved
  • 48. © 2016 ServiceNow All Rights Reserved 48Confidential 48 #Know18 © 2018 ServiceNow All Rights Reserved Travis Toulson Sr. Architect GlideFast Consulting travis.toulson@glidefast.com Thank You