SlideShare a Scribd company logo
Client-side Rendering with AngularJS 
OpenStack Summit, Paris 
David Lapsley 
@devlaps, dlapsley@cisco.com 
November 3, 2014
Client-side rendering in production
Client-side Rendering 
“Full” dataset search 
“Full” pagination Cache up to 1K records client-side
Real-time Data 
Updates every 5s 
Increased platform visibility 
Every node instrumented
Historical Metrics 
Up to 1 year of data 
Convenient access 
Increased platform visibility Every node instrumented
OpenStack Horizon 
Architecture
Django Stack
Horizon Stack
Horizon Stack Extended
AngularJS
Core concepts 
● Model View Controller framework 
● Client-side templates 
● Data binding 
● Dependency injection
Hello World 
index.html 
<html ng-app> 
<head> 
<script src="angular.js"></script> 
<script src="controllers.js"></script> 
</head> 
<body> 
<div ng-controller='HelloController'> 
<p>{{greeting.text}}, World</p> 
<button ng-click="action()">Alert</button> 
</div> 
</body> 
</html> 
controllers.js 
function HelloController($scope) { 
$scope.greeting = { text: 'Hello' }; 
$scope.action = function() { 
alert('Action!'); 
}; 
} 
AngularJS 
By: Brad Green; Shyam Seshadri 
Publisher: O'Reilly Media, Inc. 
Pub. Date: April 23, 2013
Hello World
Hello World
Adding a new Horizon feature 
with AngularJS
Directory Structure 
openstacksummit/ 
hypervisors/ 
__init__.py 
panel.py 
urls.py 
views.py 
tables.py 
tests.py 
templates/openstacksummit/hypervisors/ 
index.html 
static/openstacksummit/hypervisors/js/ 
hypervisors-controller.js 
rest/nova/ 
__init__.py 
hypervisor.py 
instance.py
REST Resource: hypervisors.py 
class HypervisorResource(resource.BaseNovaResource): 
pk = fields.CharField(attribute="pk", _("Primary Key"), hidden=True) 
hypervisor_hostname = fields.CharField(attribute='hypervisor_hostname', 
sortable=True, 
searchable=True) 
… 
actions = fields.ActionsField(attribute='actions', 
actions=[HypervisorViewLiveStats, 
HypervisorEnableAction, 
HypervisorDisableAction], 
title=_("Actions"), 
sortable=True) 
class Meta: 
authorization = auth.RestAuthorization() 
list_allowed_methods = ['get'] 
resource_name = '^hypervisor' 
field_order = ['pk', 'hypervisor_hostname', 'hypervisor_type', 'vcpus', 
'vcpus_used', 'memory_mb', 'memory_mb_used', 
'running_vms', 'state', 'status', 'actions']
Controller: hypervisor-controller.js 
horizonApp.controller('TableController', 
function($scope, $http) { 
$scope.headers = headers; 
$scope.title = title; 
$http.get('/rest/api/v1/nova/instance/').success( 
function(data, status, headers, config) { 
$scope.instances = transform(data.objects); 
}); 
}); 
horizonApp.controller('ActionDropdownController', 
function($scope) { 
$scope.status = { 
isopen: false 
}; 
$scope.toggleDropdown = function($event) { 
$event.preventDefault(); 
$event.stopPropagation(); 
$scope.status.isopen = !$scope.status.isopen; 
}; 
$scope.action = function(action, id) { 
// Perform action. 
}; 
… 
});
View: index.html 
{% extends 'base.html' %} 
{% load i18n horizon humanize sizeformat %} 
{% block title %}{% trans 'Hypervisors' %}{% endblock %} 
{% block page_header %} 
{% include 'horizon/common/_page_header.html' with title=_('All 
Hypervisors') %} 
{% endblock page_header %} 
{% block main %}
View: index.html 
<div ng-controller="TableController"> 
<table class="..."> 
<thead> 
<tr class="..."> 
<th class="..."> 
<h3 class="...">{$ title $}</h3> 
</th> 
</tr> 
<tr class="..."> 
<th class="..." ng-repeat='header in headers'> 
<div class="...">{$ header.name $}</div> 
</th> 
</tr> 
</thead>
View: index.html 
<tr ng-repeat="instance in instances"> 
<td ng-repeat="datum in instance.data">{$ datum $}</td> 
<td class="..."> 
<div ng-controller="ActionDropdownController"> 
<div class="..." dropdown> 
<button class="..." 
ng-click="action(instance.actions[0], instance.name)"> 
{$ instance.actions[0].verbose_name $} 
</button> 
... 
<div class="..."> 
<li class="..." ng-repeat="action in instance.actions"> 
<a href="#" class="..." 
ng-click="$parent.action(action,parent.instance.name)"> 
{$ action.verbose_name $} 
</a> 
</li> 
</ul> 
</div> 
</td> 
</tr> 
</table>
Client-side Rendering 
“Full” dataset search 
“Full” pagination Cache up to 1K records client-side
Why?
Advantages 
● Clean split between server and client side 
● Significantly cleaner, terser, easier to 
understand client-side code 
● Significant easier to improve UX 
● Client- and server-side code can be 
developed and tested independently 
● Faster feature velocity
Better UX 
Faster!
Thank You 
David Lapsley 
@devlaps, david.lapsley@metacloud.com
If this sounds interesting… 
http://jobs.metacloud.com 
We are hiring!
Client-side Rendering with AngularJS
Ad

Recommended

20141001 delapsley-oc-openstack-final
20141001 delapsley-oc-openstack-final
David Lapsley
 
20140821 delapsley-cloudopen-public
20140821 delapsley-cloudopen-public
David Lapsley
 
20141002 delapsley-socalangularjs-final
20141002 delapsley-socalangularjs-final
David Lapsley
 
OpenStack Horizon: Controlling the Cloud using Django
OpenStack Horizon: Controlling the Cloud using Django
David Lapsley
 
ERGroupware
ERGroupware
WO Community
 
iOS for ERREST - alternative version
iOS for ERREST - alternative version
WO Community
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using Room
Nelson Glauber Leal
 
Reporting solutions for ADF Applications
Reporting solutions for ADF Applications
Getting value from IoT, Integration and Data Analytics
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
Robert DeLuca
 
An ADF Special Report
An ADF Special Report
Luc Bors
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
Nelson Glauber Leal
 
Simplify AJAX using jQuery
Simplify AJAX using jQuery
Siva Arunachalam
 
Drupal 8: Fields reborn
Drupal 8: Fields reborn
Pablo López Escobés
 
Flask and Angular: An approach to build robust platforms
Flask and Angular: An approach to build robust platforms
Ayush Sharma
 
XQuery Rocks
XQuery Rocks
William Candillon
 
JavaScript JQUERY AJAX
JavaScript JQUERY AJAX
Makarand Bhatambarekar
 
Not your Grandma's XQuery
Not your Grandma's XQuery
William Candillon
 
Upgrade your javascript to drupal 8
Upgrade your javascript to drupal 8
Théodore Biadala
 
Building data flows with Celery and SQLAlchemy
Building data flows with Celery and SQLAlchemy
Roger Barnes
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
Roel Hartman
 
Google cloud datastore driver for Google Apps Script DB abstraction
Google cloud datastore driver for Google Apps Script DB abstraction
Bruce McPherson
 
Stratalux Cloud Formation and Chef Integration Presentation
Stratalux Cloud Formation and Chef Integration Presentation
Jeremy Przygode
 
Revolution or Evolution in Page Object
Revolution or Evolution in Page Object
Artem Sokovets
 
Presentation
Presentation
Manav Prasad
 
Google apps script database abstraction exposed version
Google apps script database abstraction exposed version
Bruce McPherson
 
Developing application for Windows Phone 7 in TDD
Developing application for Windows Phone 7 in TDD
Michele Capra
 
Tweaking the interactive grid
Tweaking the interactive grid
Roel Hartman
 
Dbabstraction
Dbabstraction
Bruce McPherson
 
Opencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJS
buttyx
 
Practical AngularJS
Practical AngularJS
Wei Ru
 

More Related Content

What's hot (20)

Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
Robert DeLuca
 
An ADF Special Report
An ADF Special Report
Luc Bors
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
Nelson Glauber Leal
 
Simplify AJAX using jQuery
Simplify AJAX using jQuery
Siva Arunachalam
 
Drupal 8: Fields reborn
Drupal 8: Fields reborn
Pablo López Escobés
 
Flask and Angular: An approach to build robust platforms
Flask and Angular: An approach to build robust platforms
Ayush Sharma
 
XQuery Rocks
XQuery Rocks
William Candillon
 
JavaScript JQUERY AJAX
JavaScript JQUERY AJAX
Makarand Bhatambarekar
 
Not your Grandma's XQuery
Not your Grandma's XQuery
William Candillon
 
Upgrade your javascript to drupal 8
Upgrade your javascript to drupal 8
Théodore Biadala
 
Building data flows with Celery and SQLAlchemy
Building data flows with Celery and SQLAlchemy
Roger Barnes
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
Roel Hartman
 
Google cloud datastore driver for Google Apps Script DB abstraction
Google cloud datastore driver for Google Apps Script DB abstraction
Bruce McPherson
 
Stratalux Cloud Formation and Chef Integration Presentation
Stratalux Cloud Formation and Chef Integration Presentation
Jeremy Przygode
 
Revolution or Evolution in Page Object
Revolution or Evolution in Page Object
Artem Sokovets
 
Presentation
Presentation
Manav Prasad
 
Google apps script database abstraction exposed version
Google apps script database abstraction exposed version
Bruce McPherson
 
Developing application for Windows Phone 7 in TDD
Developing application for Windows Phone 7 in TDD
Michele Capra
 
Tweaking the interactive grid
Tweaking the interactive grid
Roel Hartman
 
Dbabstraction
Dbabstraction
Bruce McPherson
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
Robert DeLuca
 
An ADF Special Report
An ADF Special Report
Luc Bors
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
Nelson Glauber Leal
 
Simplify AJAX using jQuery
Simplify AJAX using jQuery
Siva Arunachalam
 
Flask and Angular: An approach to build robust platforms
Flask and Angular: An approach to build robust platforms
Ayush Sharma
 
Upgrade your javascript to drupal 8
Upgrade your javascript to drupal 8
Théodore Biadala
 
Building data flows with Celery and SQLAlchemy
Building data flows with Celery and SQLAlchemy
Roger Barnes
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
Roel Hartman
 
Google cloud datastore driver for Google Apps Script DB abstraction
Google cloud datastore driver for Google Apps Script DB abstraction
Bruce McPherson
 
Stratalux Cloud Formation and Chef Integration Presentation
Stratalux Cloud Formation and Chef Integration Presentation
Jeremy Przygode
 
Revolution or Evolution in Page Object
Revolution or Evolution in Page Object
Artem Sokovets
 
Google apps script database abstraction exposed version
Google apps script database abstraction exposed version
Bruce McPherson
 
Developing application for Windows Phone 7 in TDD
Developing application for Windows Phone 7 in TDD
Michele Capra
 
Tweaking the interactive grid
Tweaking the interactive grid
Roel Hartman
 

Similar to Client-side Rendering with AngularJS (20)

Opencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJS
buttyx
 
Practical AngularJS
Practical AngularJS
Wei Ru
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
HTML5: huh, what is it good for?
HTML5: huh, what is it good for?
Remy Sharp
 
AnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFaces
Ankara JUG
 
Controller in AngularJS
Controller in AngularJS
Brajesh Yadav
 
Android Best Practices
Android Best Practices
Yekmer Simsek
 
混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver
yangdj
 
After max+phonegap
After max+phonegap
yangdj
 
MEAN - Notes from the field (Full-Stack Development with Javascript)
MEAN - Notes from the field (Full-Stack Development with Javascript)
Chris Clarke
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
Francois Zaninotto
 
E3 appspresso hands on lab
E3 appspresso hands on lab
NAVER D2
 
E2 appspresso hands on lab
E2 appspresso hands on lab
NAVER D2
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" Domino
Rob Bontekoe
 
Rails is not just Ruby
Rails is not just Ruby
Marco Otte-Witte
 
Primefaces Nextgen Lju
Primefaces Nextgen Lju
Skills Matter
 
Primefaces Nextgen Lju
Primefaces Nextgen Lju
Skills Matter
 
Angular Tutorial Freshers and Experienced
Angular Tutorial Freshers and Experienced
rajkamaltibacademy
 
The Rails Way
The Rails Way
Michał Orman
 
AngularJS Mobile Warsaw 20-10-2014
AngularJS Mobile Warsaw 20-10-2014
Dariusz Kalbarczyk
 
Opencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJS
buttyx
 
Practical AngularJS
Practical AngularJS
Wei Ru
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
HTML5: huh, what is it good for?
HTML5: huh, what is it good for?
Remy Sharp
 
AnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFaces
Ankara JUG
 
Controller in AngularJS
Controller in AngularJS
Brajesh Yadav
 
Android Best Practices
Android Best Practices
Yekmer Simsek
 
混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver
yangdj
 
After max+phonegap
After max+phonegap
yangdj
 
MEAN - Notes from the field (Full-Stack Development with Javascript)
MEAN - Notes from the field (Full-Stack Development with Javascript)
Chris Clarke
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
Francois Zaninotto
 
E3 appspresso hands on lab
E3 appspresso hands on lab
NAVER D2
 
E2 appspresso hands on lab
E2 appspresso hands on lab
NAVER D2
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" Domino
Rob Bontekoe
 
Primefaces Nextgen Lju
Primefaces Nextgen Lju
Skills Matter
 
Primefaces Nextgen Lju
Primefaces Nextgen Lju
Skills Matter
 
Angular Tutorial Freshers and Experienced
Angular Tutorial Freshers and Experienced
rajkamaltibacademy
 
AngularJS Mobile Warsaw 20-10-2014
AngularJS Mobile Warsaw 20-10-2014
Dariusz Kalbarczyk
 
Ad

More from David Lapsley (7)

Learn you some Ansible for great good!
Learn you some Ansible for great good!
David Lapsley
 
VXLAN Distributed Service Node
VXLAN Distributed Service Node
David Lapsley
 
Empowering Admins by taking away root (Improving platform visibility in Horizon)
Empowering Admins by taking away root (Improving platform visibility in Horizon)
David Lapsley
 
Real-time Statistics with Horizon
Real-time Statistics with Horizon
David Lapsley
 
Openstack Quantum Security Groups Session
Openstack Quantum Security Groups Session
David Lapsley
 
Openstack Quantum + Devstack Tutorial
Openstack Quantum + Devstack Tutorial
David Lapsley
 
Openstack Nova and Quantum
Openstack Nova and Quantum
David Lapsley
 
Learn you some Ansible for great good!
Learn you some Ansible for great good!
David Lapsley
 
VXLAN Distributed Service Node
VXLAN Distributed Service Node
David Lapsley
 
Empowering Admins by taking away root (Improving platform visibility in Horizon)
Empowering Admins by taking away root (Improving platform visibility in Horizon)
David Lapsley
 
Real-time Statistics with Horizon
Real-time Statistics with Horizon
David Lapsley
 
Openstack Quantum Security Groups Session
Openstack Quantum Security Groups Session
David Lapsley
 
Openstack Quantum + Devstack Tutorial
Openstack Quantum + Devstack Tutorial
David Lapsley
 
Openstack Nova and Quantum
Openstack Nova and Quantum
David Lapsley
 
Ad

Recently uploaded (20)

ChatGPT A.I. Powered Chatbot and Popularization.pdf
ChatGPT A.I. Powered Chatbot and Popularization.pdf
StanleySamson1
 
Clive Dickens RedTech Public Copy - Collaborate or Die
Clive Dickens RedTech Public Copy - Collaborate or Die
Clive Dickens
 
history of internet in nepal Class-8 (sparsha).pptx
history of internet in nepal Class-8 (sparsha).pptx
SPARSH508080
 
B M Mostofa Kamal Al-Azad [Document & Localization Expert]
B M Mostofa Kamal Al-Azad [Document & Localization Expert]
Mostofa Kamal Al-Azad
 
PROCESS FOR CREATION OF BUSINESS PARTNER IN SAP
PROCESS FOR CREATION OF BUSINESS PARTNER IN SAP
AhmadAli716831
 
Pitch PitchPitchPitchPitchPitchPitch.pptx
Pitch PitchPitchPitchPitchPitchPitch.pptx
157551
 
Slides: Eco Economic Epochs for The World Game (s) pdf
Slides: Eco Economic Epochs for The World Game (s) pdf
Steven McGee
 
最新版加拿大奎斯特大学毕业证(QUC毕业证书)原版定制
最新版加拿大奎斯特大学毕业证(QUC毕业证书)原版定制
taqyed
 
最新版美国特拉华大学毕业证(UDel毕业证书)原版定制
最新版美国特拉华大学毕业证(UDel毕业证书)原版定制
taqyea
 
Lecture 3.1 Analysing the Global Business Environment .pptx
Lecture 3.1 Analysing the Global Business Environment .pptx
shofalbsb
 
BASICS OF SAP _ ALL ABOUT SAP _WHY SAP OVER ANY OTHER ERP SYSTEM
BASICS OF SAP _ ALL ABOUT SAP _WHY SAP OVER ANY OTHER ERP SYSTEM
AhmadAli716831
 
原版澳洲斯文本科技大学毕业证(SUT毕业证书)如何办理
原版澳洲斯文本科技大学毕业证(SUT毕业证书)如何办理
taqyed
 
IAREUOUSTPIDWHY$)CHARACTERARERWUEEJJSKWNSND
IAREUOUSTPIDWHY$)CHARACTERARERWUEEJJSKWNSND
notgachabite123
 
Make DDoS expensive for the threat actors
Make DDoS expensive for the threat actors
APNIC
 
Topic 2 - Cloud Computing Basics,,,.pptx
Topic 2 - Cloud Computing Basics,,,.pptx
oneillp100
 
Logging and Automated Alerting Webinar.pdf
Logging and Automated Alerting Webinar.pdf
ControlCase
 
原版一样(ISM毕业证书)德国多特蒙德国际管理学院毕业证多少钱
原版一样(ISM毕业证书)德国多特蒙德国际管理学院毕业证多少钱
taqyed
 
ChatGPT_and_Its_Uses_Presentationss.pptx
ChatGPT_and_Its_Uses_Presentationss.pptx
Neha Prakash
 
Topic 1 Foundational IT Infrastructure_.pptx
Topic 1 Foundational IT Infrastructure_.pptx
oneillp100
 
Almos Entirely Correct Mixing with Apps to Voting
Almos Entirely Correct Mixing with Apps to Voting
gapati2964
 
ChatGPT A.I. Powered Chatbot and Popularization.pdf
ChatGPT A.I. Powered Chatbot and Popularization.pdf
StanleySamson1
 
Clive Dickens RedTech Public Copy - Collaborate or Die
Clive Dickens RedTech Public Copy - Collaborate or Die
Clive Dickens
 
history of internet in nepal Class-8 (sparsha).pptx
history of internet in nepal Class-8 (sparsha).pptx
SPARSH508080
 
B M Mostofa Kamal Al-Azad [Document & Localization Expert]
B M Mostofa Kamal Al-Azad [Document & Localization Expert]
Mostofa Kamal Al-Azad
 
PROCESS FOR CREATION OF BUSINESS PARTNER IN SAP
PROCESS FOR CREATION OF BUSINESS PARTNER IN SAP
AhmadAli716831
 
Pitch PitchPitchPitchPitchPitchPitch.pptx
Pitch PitchPitchPitchPitchPitchPitch.pptx
157551
 
Slides: Eco Economic Epochs for The World Game (s) pdf
Slides: Eco Economic Epochs for The World Game (s) pdf
Steven McGee
 
最新版加拿大奎斯特大学毕业证(QUC毕业证书)原版定制
最新版加拿大奎斯特大学毕业证(QUC毕业证书)原版定制
taqyed
 
最新版美国特拉华大学毕业证(UDel毕业证书)原版定制
最新版美国特拉华大学毕业证(UDel毕业证书)原版定制
taqyea
 
Lecture 3.1 Analysing the Global Business Environment .pptx
Lecture 3.1 Analysing the Global Business Environment .pptx
shofalbsb
 
BASICS OF SAP _ ALL ABOUT SAP _WHY SAP OVER ANY OTHER ERP SYSTEM
BASICS OF SAP _ ALL ABOUT SAP _WHY SAP OVER ANY OTHER ERP SYSTEM
AhmadAli716831
 
原版澳洲斯文本科技大学毕业证(SUT毕业证书)如何办理
原版澳洲斯文本科技大学毕业证(SUT毕业证书)如何办理
taqyed
 
IAREUOUSTPIDWHY$)CHARACTERARERWUEEJJSKWNSND
IAREUOUSTPIDWHY$)CHARACTERARERWUEEJJSKWNSND
notgachabite123
 
Make DDoS expensive for the threat actors
Make DDoS expensive for the threat actors
APNIC
 
Topic 2 - Cloud Computing Basics,,,.pptx
Topic 2 - Cloud Computing Basics,,,.pptx
oneillp100
 
Logging and Automated Alerting Webinar.pdf
Logging and Automated Alerting Webinar.pdf
ControlCase
 
原版一样(ISM毕业证书)德国多特蒙德国际管理学院毕业证多少钱
原版一样(ISM毕业证书)德国多特蒙德国际管理学院毕业证多少钱
taqyed
 
ChatGPT_and_Its_Uses_Presentationss.pptx
ChatGPT_and_Its_Uses_Presentationss.pptx
Neha Prakash
 
Topic 1 Foundational IT Infrastructure_.pptx
Topic 1 Foundational IT Infrastructure_.pptx
oneillp100
 
Almos Entirely Correct Mixing with Apps to Voting
Almos Entirely Correct Mixing with Apps to Voting
gapati2964
 

Client-side Rendering with AngularJS

  • 1. Client-side Rendering with AngularJS OpenStack Summit, Paris David Lapsley @devlaps, [email protected] November 3, 2014
  • 3. Client-side Rendering “Full” dataset search “Full” pagination Cache up to 1K records client-side
  • 4. Real-time Data Updates every 5s Increased platform visibility Every node instrumented
  • 5. Historical Metrics Up to 1 year of data Convenient access Increased platform visibility Every node instrumented
  • 11. Core concepts ● Model View Controller framework ● Client-side templates ● Data binding ● Dependency injection
  • 12. Hello World index.html <html ng-app> <head> <script src="angular.js"></script> <script src="controllers.js"></script> </head> <body> <div ng-controller='HelloController'> <p>{{greeting.text}}, World</p> <button ng-click="action()">Alert</button> </div> </body> </html> controllers.js function HelloController($scope) { $scope.greeting = { text: 'Hello' }; $scope.action = function() { alert('Action!'); }; } AngularJS By: Brad Green; Shyam Seshadri Publisher: O'Reilly Media, Inc. Pub. Date: April 23, 2013
  • 15. Adding a new Horizon feature with AngularJS
  • 16. Directory Structure openstacksummit/ hypervisors/ __init__.py panel.py urls.py views.py tables.py tests.py templates/openstacksummit/hypervisors/ index.html static/openstacksummit/hypervisors/js/ hypervisors-controller.js rest/nova/ __init__.py hypervisor.py instance.py
  • 17. REST Resource: hypervisors.py class HypervisorResource(resource.BaseNovaResource): pk = fields.CharField(attribute="pk", _("Primary Key"), hidden=True) hypervisor_hostname = fields.CharField(attribute='hypervisor_hostname', sortable=True, searchable=True) … actions = fields.ActionsField(attribute='actions', actions=[HypervisorViewLiveStats, HypervisorEnableAction, HypervisorDisableAction], title=_("Actions"), sortable=True) class Meta: authorization = auth.RestAuthorization() list_allowed_methods = ['get'] resource_name = '^hypervisor' field_order = ['pk', 'hypervisor_hostname', 'hypervisor_type', 'vcpus', 'vcpus_used', 'memory_mb', 'memory_mb_used', 'running_vms', 'state', 'status', 'actions']
  • 18. Controller: hypervisor-controller.js horizonApp.controller('TableController', function($scope, $http) { $scope.headers = headers; $scope.title = title; $http.get('/rest/api/v1/nova/instance/').success( function(data, status, headers, config) { $scope.instances = transform(data.objects); }); }); horizonApp.controller('ActionDropdownController', function($scope) { $scope.status = { isopen: false }; $scope.toggleDropdown = function($event) { $event.preventDefault(); $event.stopPropagation(); $scope.status.isopen = !$scope.status.isopen; }; $scope.action = function(action, id) { // Perform action. }; … });
  • 19. View: index.html {% extends 'base.html' %} {% load i18n horizon humanize sizeformat %} {% block title %}{% trans 'Hypervisors' %}{% endblock %} {% block page_header %} {% include 'horizon/common/_page_header.html' with title=_('All Hypervisors') %} {% endblock page_header %} {% block main %}
  • 20. View: index.html <div ng-controller="TableController"> <table class="..."> <thead> <tr class="..."> <th class="..."> <h3 class="...">{$ title $}</h3> </th> </tr> <tr class="..."> <th class="..." ng-repeat='header in headers'> <div class="...">{$ header.name $}</div> </th> </tr> </thead>
  • 21. View: index.html <tr ng-repeat="instance in instances"> <td ng-repeat="datum in instance.data">{$ datum $}</td> <td class="..."> <div ng-controller="ActionDropdownController"> <div class="..." dropdown> <button class="..." ng-click="action(instance.actions[0], instance.name)"> {$ instance.actions[0].verbose_name $} </button> ... <div class="..."> <li class="..." ng-repeat="action in instance.actions"> <a href="#" class="..." ng-click="$parent.action(action,parent.instance.name)"> {$ action.verbose_name $} </a> </li> </ul> </div> </td> </tr> </table>
  • 22. Client-side Rendering “Full” dataset search “Full” pagination Cache up to 1K records client-side
  • 23. Why?
  • 24. Advantages ● Clean split between server and client side ● Significantly cleaner, terser, easier to understand client-side code ● Significant easier to improve UX ● Client- and server-side code can be developed and tested independently ● Faster feature velocity
  • 26. Thank You David Lapsley @devlaps, [email protected]
  • 27. If this sounds interesting… http://jobs.metacloud.com We are hiring!

Editor's Notes

  • #4: Server provides data over RESTful API – json data Client responsible for rendering and presenting Much more interactive, client can now take immediate action on data it knows about instead of round tripping to server Faster feature velocity, server and client can be developed in parallel Simpler code
  • #5: Instrument each node with livestastd Controllers and Hypervisors Pull information about processes, network, disk, cpu Updates every 5 seconds Using the same client-side rendering pattern as before Aggregating real-time data Greatly increases visibility into platform..
  • #6: Our customers also wanted to see more historical data. We instrumented all of our nodes and push data into Graphite Very high performance and flexiblie time series tool Evolution of RRD Tool Graphite provides data over RESTful API, so we just pull that data and use it to populate these charts.. Easy access for the user (simply click on controller or hypervisor row and chart will drop down) Data from 1 hour range to 1 year range..
  • #9: Add client-side…
  • #19: Controls view logic
  • #27: Collaborate, share our experience, find out if there are better ways of doing things