The buzz about the upcoming major reincarnation of AngularJS, with its hot mix of excitement and critics, has somehow shadowed the immediate gains enabled by the recent 1.3 and 1.4 releases.
This code-based talk will introduce concepts such as the "Controller As" syntax, component-based directives, the new router and bind once, to demonstrate how mixing these currently available Angular features with good design patterns (and a bit of ES6) provides concrete improvements in performance, modularity, testability and developer productivity to our apps now.
Furthermore, it will show how the main ideas at the basis of Angular 2.0 (API simplification, consistency, even more componentization and interoperability with ES6 and Web Components) can be applied to the design and implementation of 1.x applications, helping us both being more productive now & simplifying the upgrade to the "new" Angular.
Active Directory Penetration Testing, cionsystems.com.pdf
Angular 1.x reloaded: improve your app now! and get ready for 2.0
1. #vdt15 @carlobonamico
Angular 1.x reloaded:
improve your app now! and get ready for 2.0
Carlo Bonamico
NIS s.r.l. / JUG Genova
carlo.bonamico@nispro.it
2. #vdt15 @carlobonamico
Waiting for Angular 2.0
● As development proceeds and details emerge, growing excitement
for what the new release will bring:
– full support for Web Components
● which often require custom integration directives in AngularJS 1.x
– full support for ES6
● particularly module system
– better performance
– better tooling support
● smart autocompletion, development-time validation
– first-class mobile support
● By the way, go watch Misko and Rado Kirov ng-conf Day 2 keynote
– videos for all other talks also available
● https://www.youtube.com/watch?v=-dMBcqwvYA0&index=21&list=PLOETEcp3DkCoNnlhE-7fov
YvqwVPrRiY7
https://angular.io
3. #vdt15 @carlobonamico
Yes, but... The questions we are all asking
● Do I start learning/using 2.0 now? or when?
● Will I be forced to use ES6 or Typescript?
● Will I have to rewrite some/most/all of my 1.x code?
● By the way, what the *** is this new syntax?
[disabled]=”comp.disabled” (click)=”comp.enable()”
● How about a migration path?
● Do I have to wait until 2016 to get 2.0 advantages in my app?
4. #vdt15 @carlobonamico
Some (preliminary) answers
● Do I start learning/using 2.0 now? or when?
learning, now! using... not until beta/RC
● Will I be forced to use ES6 or Typescript?
NO! although you will get benefits it you do
● Will I have to rewrite some/most/all of my 1.x code?
definitely NOT ALL – more about this later
● By the way, what the *** is this new syntax?
[disabled]=”comp.disabled” (click)=”comp.enable()”
better semantics! Web Components!
● How about a migration path?
● Do I have to wait until 2016 to get 2.0 advantages?
NO! see next slides...
● So... – and start getting ready!
Disclaimer:
1) Info uptodate
in April 2015.
2) May change:
additions possible
major API changes
look unlikely
3) I am not in the
Angular team.
All mistakes &
misinterpretations
are mine :)
5. #vdt15 @carlobonamico
You can improve your 1.x app now,
AND make adoption of 2.0 easier
● Use new (and 2.x friendly) constructs
– controllerAs
– new bindToController directive syntax
● Follow 2.0 Design Patterns now
– components all the way down
● Use “dual mode” libraries supporting both versions
– angular new router
– i18n
– more to follow...
● Take advantage of ES6 / TypeScript
This talk is
shares our experience
in adopting these approaches
in real-world projects
6. #vdt15 @carlobonamico
What's new in 1.3/1.4?
● Apparently, small things
– but they do enable big changes in the way we develop Angular apps
● Besides, both releases achieve a significant performance increase
– 1.3 improves DOM manipulation
● 4.3 times faster with 73% less garbage
– 1.3 optimizes change detection
● 3.5 times faster digest with 87% less garbage
– 1.4 brings even more tuning
– you do not need to change your code :-)
● So move to 1.3 NOW!
– and to 1.4 in a few weeks (it's RC0 as of today)
7. #vdt15 @carlobonamico
Angular 1.x reloaded – 1: controllerAs
● Avoid injecting $scope in the controller
● Put the controller instance IN the scope
● HTML
<div ngcontroller=”ComposerController as msgComposer”>
{{msgComposer.message.subject}}
<button ngclick=”msgComposer.send()”>
</div>
● JS
function ComposerController(MailService) //no $scope!
{
this.message = { subject : “Hello World” };
this.send = function () { MailService.send(this.message); };
}
angular.module(“mailApp”).controller(“ComposerCtrl”, ComposerController)
Examples for a fictional
gmail-like webmail
8. #vdt15 @carlobonamico
Advantages
● More readable code
– particularly in complex views
● Even easier to test
● Use the $scope only if need access to its APIs
– e.g. $watch()
● http://toddmotto.com/digging-into-angulars-controller-as-syntax/
– less dependencies on the framework
● and consequently on the framework version
● Why is this important?
– no explicit scope in 2.0 → becomes integrated with Dep. Injection
– @Component syntax similar to controllerAs
9. #vdt15 @carlobonamico
Angular 1.x reloaded - 2: Use ES6 / TypeScript
● ES6: the future of the web
– both class support and better functional programming constructs
● Standard module system
– including good support for both sync and async loading
● TypeScript adds types (both explicit and inferred)
– more development-time checks
● Good news is that they are optional!
– so that use them only where they do provide benefits
– incrementally add them
● small overhead in workflow, better tooling
10. #vdt15 @carlobonamico
Example of ControllerAs: ES5
● In HTML
<div ngcontroller=”ComposerController as msgComposer”>
{{msgComposer.message.subject}}
<button ngclick=”msgComposer.send()”>
</div>
● JS
function ComposerController(MailService) //no $scope!
{
this.message = { subject : “Hello World” };
this.send = function () { MailService.send(this.message); };
}
angular.module(“mailApp”).controller(“ComposerCtrl”, ComposerController)
11. #vdt15 @carlobonamico
Example of ControllerAs: ES6
● In HTML
<div ngcontroller=”ComposerController as msgComposer”>
{{msgComposer.message.subject}}
<button ngclick=”msgComposer.send()”>
</div>
● ES6
class ComposerController
{
constructor(MailService){
this.mailService = MailService;
this.message = { subject : “Hello World” };
}
send() { this.mailService.send(this.message); };
}
angular.module(“mailApp”).controller(“ComposerCtrl”, ComposerController)
12. #vdt15 @carlobonamico
Example of ControllerAs: TypeScript
● In HTML
<div ngcontroller=”ComposerController as msgComposer”>
{{msgComposer.message.subject}}
<button ngclick=”msgComposer.send()”>
</div>
● TS
class ComposerController
{
message:MailMessage;
constructor(private mailService:MailService){ //autoassign to property
this.message = { subject : “Hello World” };
}
send() { this.mailService.send(this.message); };
}
angular.module(“mailApp”).controller(“ComposerCtrl”, ComposerController)
13. #vdt15 @carlobonamico
Example of Angular 2.0 Component
● In composer.html
<div>
{{message.subject}}
<button (click)=”send()”>
</div>
● TS
@Component({ selector: "messagecomposer"}, inject: ...)
@Template({url: "composer.html"})
class ComposerController
{
message: MailMessage;
constructor(private mailService:MailService){
this.message = { subject : “Hello World” };
}
send() { this.mailService.send(this.message); };
}
angular.module(“mailApp”).controller(“ComposerCtrl”, ComposerController)
● http://blog.ionic.io/angular-2-series-components/
@Metadata
Can also be written in
(slightly more verbose)
ES5 syntax
14. #vdt15 @carlobonamico
What about AtScript? ES6 – TypeScript roadmap
● At ng-conf 2015, Microsoft & Angular Team announced that
AtScript features (particularly annotations and runtime types)
are being merged into TypeScript 1.5
● http://blogs.msdn.com/b/typescript/archive/2015/03/05/angular-2-0-built-on-typescript.a
spx
Now - at TypeScript 2.0 release
– at runtime, both languages share the current ES5 object model
TS
ES6
ES5 TSES6 ES5
15. #vdt15 @carlobonamico
But tell me more about the migration path...
● There will be one! “1.x will evolve until migration is trivial”
– Main theme of Angular 1.5: paving the way to the upgrade
● In the meantime: good old Software Engineering principles still apply!
– Separation of Concerns (particularly UI - logic)
– Clarity of intent and code readability
– Favor composition over inheritance
– Modularity
– Test, test, test!
● unit (Jasmine) vs e2e (protractor – cucumber) - http://martinfowler.com/bliki/TestPyramid.html
● As always, apps following these principles will adapt more easily to
both requirements changes and framework changes
– and it will be easier to evolve them incrementally
– and validating each step → see Continuous Delivery
16. #vdt15 @carlobonamico
Composition and Separation of Concerns: from this
Image courtesy of Todd Motto's very interesting tutorial
https://www.thinkful.com/learn/angularjs-tutorial-build-a-gmail-clone
WebMailController
17. #vdt15 @carlobonamico
Composition and Separation of Concerns: to this
WebMailController
MessageListController
FolderList
Controller MsgAction
Controller
Controllers
should be as small
as possible
should be “slim”,
manage link to UI,
and delegate
to Services
MessageListService
MailSenderService
● Angular 2.0 will have much better and more powerful DI,
● but actual Service code will not change much
18. #vdt15 @carlobonamico
Angular 1.x reloaded – 3: DataBinding
● 1.3 adds support for one-time binding with {{ ::obj.field }}
– better performance with immutable data
– reduces the need for custom directives
<li
ngrepeat=”item in hugeListOfNonChangingItems”>
{{ ::item.name }}</li>
● Limitations of 1.x binding: what is name in
<tag search=”name”>
– a string constant? and expression? do I need curly braces?
– is it an attribute or a method?
● Implicit semantics! it depends on the DDO...
– not self-describing
1.x Binding Syntax Binding Type
{{obj.field}} model-to-view
{{::obj.field }} model-to-view,
one-time
ngmodel=”obj.field” bidirectional
ngclick=”add()” event method
19. #vdt15 @carlobonamico
Angular 2.0: New binding syntax?
no, new binding semantics!
● Angular 1.x binds to HTML attributes
– parsed and processed by the $compile service
● Angular 2.0 binds to DOM properties – HTML seen as serialized DOM
[text]=”composer.message.subject” means bind → text property value to variable
(click)=”composer.send()” means attach listener to → click event
● Advantages
– no more ad-hoc directives
use standard dom properties
– works with any Web Component
<tab [title]=”message.subject” (click)=”collapse()” >
– unambiguous and self-describing
● expression format specified by the caller, not by the component
– more readable, clearer flow of data within the page
● once your eyes get accustomed to the parentheses :-)
nghide=”” → [hidden]=””
ngclick=”” → (click)=””
or canonical syntax
nghide=”” →bindhidden=””
ngclick=”” →onclick=””
20. #vdt15 @carlobonamico
Is this all?
● Data binding syntax is just the tip of the iceberg...
● So what's the single most important thing that you can do now
to get ready for 2.0?
{{ iceberg.tip }}
Modules DI
Routing
components
21. #vdt15 @carlobonamico
Move to component-based development now
● From this
ngcontroller=”WebMailController”
ngcontroller=”MessageListController”
MessageList.html
Ngcontroller
=
”FolderList
Controller” MsgAction
Controller
22. #vdt15 @carlobonamico
Move to component-based development now
● To this
ngcontroller=”WebMailController”
<messagelist><folderlist>
<messageactions>
<messagedetails>
<messagesearchbox>
23. #vdt15 @carlobonamico
With component-based directives
● Angular 2.0 will be both component-based and component-
friendly
– the default construct will be a component
– controllers and directives become components with different roles
● Three different roles
Role Angular 1.x Angular 2.0
Element restrict: “E”, scope: { … }
can use transclusion
@Component
can use shadow-dom
Decorator restrict: “A”, link: function
(element)
@Decorator
constructor(element)
Template/Viewport e.g. ng-repeat
ng-if
e.g. *for
*if
24. #vdt15 @carlobonamico
Angular 1.x reloaded – 4: better component support
with bindToController
used in HTML
<messagecomposer
message=”ctrl.newMessage”
autosave=”true”
ondraftsave=”mainCtrl.save()”>
</messagecomposer>
Template
Subject: <input
ngmodel=”compCtrl.message.subject”>
Content: <input
ngmodel=”compCtrl.message.content”>
<button ngclick=”compCtrl.save()”>
Save</button>
<button ngclick=”compCtrl.send()”>
Send</button>
app.directive('messageComposer',
function () {
return {
scope: {},
bindToController: {
message: '=',
autosave: '@',
onDraftSave: '&'
onSend: '&'
}
templateUrl: … ,
controller: 'ComposerCtrl as compCtrl', };
});
class ComposerCtrl {
message = {...};
constructor(){
this.autosave = true;
}
save (){
//do stuff
this.onDraftSave(this.message);
}
}
25. #vdt15 @carlobonamico
But if everything is a component,
● How do they share state?
● Do they?
● How do they interact?
26. #vdt15 @carlobonamico
Example: message list with expanded current
message and navigation
● Within FolderController of <messagefoldercontent>
<messagelist>
<messagedetails>
<< >><navigationcontrols>
<messagedetails>
27. #vdt15 @carlobonamico
Connecting components: defining an API
● A component has
– inputs: bindable properties
● and component methods in 2.0
– outputs: event methods
● A bit like a function with input parameters and output callbacks
● In our example
Component Inputs Outputs
<messagelist> list
<messagedetails> message, collapse() reply(), forward()
<navigationcontrols> next(), prev()
29. #vdt15 @carlobonamico
Connecting components: binding and data flow
● Within <messagefoldercontent name=”inbox”>
<messagelist list=”folder.messages”>
<< >><navigationcontrols prev=””>
<messagedetails
message=”folder.current”>
Direct Acyclic Graph!
i.e. a Good Thing
30. #vdt15 @carlobonamico
Connecting components: state and data flow
● In 1.x state is often hidden
– many components can change shared state in any direction
● thanks to two-way DataBinding
● Two way DataBinding is extremely powerful
– we got hooked into Angular because of this
● Turns out, however, that
– two-way binding works best at the local level
– too implicit in complex / composite views
31. #vdt15 @carlobonamico
What about two-way DataBinding?
● So a bit like you refactor global variables into encapsulated state with explicit
parameter passing, in 2.x, component state can be shared through data
binding only with child components
<messagedetails message=”currentMessage”>
– binding lets a child component read its parent state, not write to it
– child components need explicit event methods to communicate state change to
surrounding components
● e.g. next()
● Page structure and data flow becomes easier to follow
– particularly in complex apps
● But... forms likely to get ad-hoc support replicating two-way behaviour
with different implementation
– http://victorsavkin.com/post/110170125256/change-detection-in-angular-2
32. #vdt15 @carlobonamico
Advantages
● Dependencies become more explicit
● State changes can be propagated even more efficiently
– model → view from top to bottom
– view → model explicitly, and bottom-up
● This means fast fast FAST! databinding
– single-pass change detection
● http://victorsavkin.com/post/114168430846/two-phases-of-angular-2-applications
– even more optimization if you give hints about when state changes
● immutable vs observable vs dirty-checked objects
● http://victorsavkin.com/post/110170125256/change-detection-in-angular-2
34. #vdt15 @carlobonamico
Use Angular 1.4 new router
https://angular.github.io/router
● Component-based router
● Supports
– child and nested router
– lazy loading
– multiple views
● JS Route configuration
$router.config([
{
path: '/inbox',
// Map components
to viewports
components: {
//folder component
in main viewport
'main': 'folder',
'sidebar': 'folderlist'
}
]);
<div
ngview
port
="side
bar">
<div ngviewport="main">
35. #vdt15 @carlobonamico
The new router – lifecycle support
● Promise-enabled callbacks before and after navigation
– notify navigation requests
– can accept / reject them
● Simplifies many common use cases:
– asking confirmation before leaving view with unsaved data in forms
– redirecting to login page if not auhtenticated
– block navigation to routes not authorized for the user profile
● It will support mixed 1.x / 2.0 scenarios:
– 1.x views in 2.0 route definition and vice-versa
– key tool for incremental migration of large apps
● https://www.youtube.com/watch?v=vecg70fPDFw
36. #vdt15 @carlobonamico
Next Generation modules
● Learn about System.js
– backward- and forward- compatible
implementation of ES6 module system
– available now!
– https://github.com/systemjs/systemjs
● Example for Angular 1.x
– http://martinmicunda.com/2015/02/09/how-to-start-writing-apps-wit
h-es6-angular-1x-and-jspm/
● Example for Angular 2.0
– https://angular.io/docs/js/latest/quickstart.html
Webmail App
Logging Auth UI Widgets
Message
List
Reader
Message
Composer
Contacts
37. #vdt15 @carlobonamico
Keep up-to-date
● Watch out for 1.5 release
– main theme adding support for easier migration
– keep an eye on http://angularjs.blogspot.it/ for roadmap updates
● Learn about Component-based approaches with 1.x
– https://www.airpair.com/javascript/posts/creating-container-components
-part-1-shadow-dom
(also part 2 & part 3)
● Start reading about 2.0
– http://blog.ionic.io/angular-2-series-introduction/
– http://blog.thoughtram.io/
– https://github.com/timjacobi/angular2-education
● Follow 2.x development
– http://victorsavkin.com/
39. #vdt15 @carlobonamico
Thank you!
● If you are interested,
– read my other presentations
● http://www.slideshare.net/carlo.bonamico/presentations
– ask us about Angular training / consulting
● http://www.nispro.it
● Follow us on Twitter
– @carlobonamico @nis_srl
● updates on AngularJS!
● and some Docker, Ansible, Continuous Delivery
● Contact us
– carlo.bonamico@gmail.com / carlo.bonamico@nispro.it
Special thanks to my teammates
Sonia Pini, Danilo Caruso
and Roberta Ficco for all
suggestions, ideas & feedback
on “reloading” Angular
and to Pascal Precht
for the timely & great feedback