39
#vdt15 @carlobonamico Angular 1.x reloaded: improve your app now! and get ready for 2.0 Carlo Bonamico NIS s.r.l. / JUG Genova [email protected]

Angular 1.x reloaded: improve your app now! and get ready for 2.0

Embed Size (px)

Citation preview

#vdt15 @carlobonamico

Angular 1.x reloaded: improve your app now! and get ready for 2.0

Carlo BonamicoNIS s.r.l. / JUG Genova

[email protected]

#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 

#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?

#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 up­to­date in April 2015.

2) May change: additions possiblemajor API changes 

look unlikely 

3) I am not in the Angular team.All mistakes &

misinterpretations are mine :­)

#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 isshares our experience

in adopting these approaches in real-world projects

#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)

#vdt15 @carlobonamico

Angular 1.x reloaded – 1: controllerAs

● Avoid injecting $scope in the controller● Put the controller instance IN the scope● HTML

<div ng­controller=”ComposerController as msgComposer”>{{msgComposer.message.subject}}<button ng­click=”msgComposer.send()”>

</div>

● JSfunction 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 fictionalgmail-like webmail

#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

#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

#vdt15 @carlobonamico

Example of ControllerAs: ES5

● In HTML<div ng­controller=”ComposerController as msgComposer”>

{{msgComposer.message.subject}}<button ng­click=”msgComposer.send()”>

</div>

● JSfunction ComposerController(MailService)  //no $scope!{

this.message = { subject : “Hello World” };

this.send = function () { MailService.send(this.message); };}angular.module(“mailApp”).controller(“ComposerCtrl”, ComposerController)

#vdt15 @carlobonamico

Example of ControllerAs: ES6

● In HTML<div ng­controller=”ComposerController as msgComposer”>

{{msgComposer.message.subject}}<button ng­click=”msgComposer.send()”>

</div>

● ES6class ComposerController  {

constructor(MailService){this.mailService = MailService;this.message = { subject : “Hello World” };

}

send() { this.mailService.send(this.message); };}angular.module(“mailApp”).controller(“ComposerCtrl”, ComposerController)

#vdt15 @carlobonamico

Example of ControllerAs: TypeScript

● In HTML<div ng­controller=”ComposerController as msgComposer”>

{{msgComposer.message.subject}}<button ng­click=”msgComposer.send()”>

</div>

● TSclass ComposerController  {     message:MailMessage; 

constructor(private mailService:MailService){ //auto­assign to property

this.message = { subject : “Hello World” };}

send() { this.mailService.send(this.message); };}angular.module(“mailApp”).controller(“ComposerCtrl”, ComposerController)

#vdt15 @carlobonamico

Example of Angular 2.0 Component

● In composer.html<div>

{{message.subject}}<button (click)=”send()”>

</div>

● TS@Component({ selector: "message­composer"}, 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

#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.aspx

Now - at TypeScript 2.0 release

– at runtime, both languages share the current ES5 object model

TSES6

ES5 TSES6 ES5

#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

#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

#vdt15 @carlobonamico

Composition and Separation of Concerns: to this

   WebMailController

MessageListController

FolderListController MsgAction

Controller

Controllers

should be as small as possible

should be “slim”, manage link to UI,

and delegate to Services

MessageListServiceMailSenderService

● Angular 2.0 will have much better and more powerful DI, ● but actual Service code will not change much

#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  ng­repeat=”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

ng­model=”obj.field” bidirectional

ng­click=”add()” event method

#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 :-)

ng­hide=””   → [hidden]=”” ng­click=””   → (click)=””

or canonical syntax

ng­hide=”” →bind­hidden=””ng­click=”” →on­click=””

#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

#vdt15 @carlobonamico

Move to component-based development now

● From this

     ng­controller=”WebMailController”

ng­controller=”MessageListController”MessageList.html

Ng­controller=

”FolderListController” MsgAction

Controller

#vdt15 @carlobonamico

Move to component-based development now

● To this

     ng­controller=”WebMailController”

<message­list><folder­list>

<message­actions>

<message­details>

<message­search­box>

#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 rolesRole Angular 1.x Angular 2.0

Element restrict: “E”, scope: { … }can use transclusion

@Componentcan use shadow-dom

Decorator restrict: “A”, link: function (element)

@Decoratorconstructor(element)

Template/Viewport e.g. ng-repeatng-if

e.g. *for *if

#vdt15 @carlobonamico

Angular 1.x reloaded – 4: better component support with bindToController

used in HTML

<message­composer message=”ctrl.newMessage” 

autosave=”true” on­draft­save=”mainCtrl.save()”>

</message­composer>

Template

Subject: <input ng­model=”compCtrl.message.subject”>

Content: <input ng­model=”compCtrl.message.content”>

<button ng­click=”compCtrl.save()”>Save</button>

  <button ng­click=”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);  }}

#vdt15 @carlobonamico

But if everything is a component,

●How do they share state?

●Do they?

●How do they interact?

#vdt15 @carlobonamico

Example: message list with expanded current message and navigation

● Within FolderController of <message­folder­content>

<message­list>

<message­details>

<< >><navigation­controls>

<message­details>

#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 exampleComponent Inputs Outputs

<message­list> list

<message­details> message, collapse() reply(), forward()

<navigation­controls> next(), prev()

#vdt15 @carlobonamico

Connecting components: HTML

● HTML

<message­folder­content name=”inbox”>

</message­folder­content> 

● templates/message-folder-content.html

 <message­list          list=”folder.messages”>

    <display­message      message = “folder.currentMessage”>

 </message­list>

 <navigation­controls              next=”folder.next()”            prev=”...” >

● In <message­folder­content> controllerclass FolderController{

   constructor(MessageLoaderService){

    this.messages = MessageLoaderService.loadMessagesByFolder(this.name);

    this.counter = 0;

    this.currentMessage = this.messages[counter];

   }

   next(){

    this.counter = ++;

    this.currentMessage = this.messages[counter];

   }

   reply(message) { … }

}

#vdt15 @carlobonamico

Connecting components: binding and data flow

● Within <message­folder­content name=”inbox”>

<message­list list=”folder.messages”>

<< >><navigation­controls prev=””>

<message­details message=”folder.current”>

Direct Acyclic Graph!

i.e. a Good Thing

#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

#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

<message­details 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

#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

#vdt15 @carlobonamico

Use Angular 1.4 new routerhttps://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': 'folder­list'      } ]);

<div ng­viewport="sidebar">

<div ng­viewport="main">

#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

#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-with-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

#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/

#vdt15 @carlobonamico

More references

● StyleGuide– https://github.com/johnpapa/angular­styleguide 

● SOLID Principles– http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

● Javascript by Yakov Fain – http://enterprisewebbook.com/appendix_a_advancedjs.html

– https://www.youtube.com/watch?v=X1J0oMayvC0

● Axel Rauschmayer Speaking Javascript– http://speakingjs.com/ 

● TypeScript– http://www.typescriptlang.org/

● ES6– http://www.2ality.com/2014/08/es6­today.html

#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– [email protected] / [email protected]

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