Slide 1

Slide 1 text

AngularJS 1.3 let’s talk about changes!

Slide 2

Slide 2 text

Michał Miszczyszyn JavaScript developer at The Comet Cult (mostly AngularJS) @mmiszy
 [email protected]

Slide 3

Slide 3 text

Today’s presentation: • AngularJS roadmap • 1.3.0 breaking changes • Performance improvements • New features

Slide 4

Slide 4 text

Let’s not talk about changelog

Slide 5

Slide 5 text

Let’s talk about changes code before and after Angular 1.3

Slide 6

Slide 6 text

Breaking changes

Slide 7

Slide 7 text

no IE8 support! • Won’t break the second you update, but… it might • Tests are not run on IE8 • Smaller codebase, less hacks

Slide 8

Slide 8 text

falsy values • Before, some strings were falsy: 
 'f', '0', 'false', 'no', 'n', '[]' • Before, empty array was falsy: [] • Now only JS falsy values are

Slide 9

Slide 9 text

falsy values • Before 1.3 this would display nothing: $scope.test = 'no';
Nope.
• Have we ever done it?

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

falsy values • But we did rely on this: $scope.empty = [];
Nope.
• Removed in 1.3 as well

Slide 12

Slide 12 text

replace directives • No longer supported • Difficult to implement • All browsers support custom elements

Slide 13

Slide 13 text

stateless filters • Won't update if injected data changes • Huuuge performance gain - caching • filter.$stateful = true

Slide 14

Slide 14 text

Done with the breaking changes!

Slide 15

Slide 15 text

Performance improvements

Slide 16

Slide 16 text

benchpress • Macro benchmarking tool • Performance of real applications • Measures garbage collector too • On GitHub by Angular team

Slide 17

Slide 17 text

benchpress • AngularJS 1.3 compared to 1.2: • DOM manipulation:
 4.4x faster, 73% less garbage • digest:
 3.5x faster, 87% less garbage

Slide 18

Slide 18 text

benchpress • The main point is: • Don't worry about Angular's overhead, worry about your code's performance!

Slide 19

Slide 19 text

but wait… is that all?

Slide 20

Slide 20 text

production mode • There's a lot of debug info everywhere • Some tools (eg. Protractor) use them but they're not needed in production

Slide 21

Slide 21 text

production mode • You can turn them off:
 $compileProvider
 .debugInfoEnabled(false);

Slide 22

Slide 22 text

production mode • Production mode: • DOM manipulation:
 44% faster, 73% less garbage • digest:
 28% faster

Slide 23

Slide 23 text

$httpProvider.useApplyAsync(true); • 1.2: every resolved request = digest • You can now configure it • If many responses come in a short time, only one digest will be called

Slide 24

Slide 24 text

$rootScope.$applyAsync() • You can use this in your own modules • It queues up multiple apply calls
 within about 10ms

Slide 25

Slide 25 text

cool but… boring

Slide 26

Slide 26 text

New features (the real cool stuff)

Slide 27

Slide 27 text

Material Design • It's a styleguide from Google • Angular-material-design is a set of lightweight UI elements based on it • Requires angular 1.3

Slide 28

Slide 28 text

angular-material-design • Accessible • Takes care of all ARIA attributes • Allows keyboard navigation

Slide 29

Slide 29 text

angular-material-design • Responsive • No, really. • It's very responsive.

Slide 30

Slide 30 text

angular-material-design • Turns sidebars into off-screen menus automatically • Gives really cool feedback for touch

Slide 31

Slide 31 text

angular-material-design • Super easy to use • Built with flexbox • Integration with ionic is coming… • material.angularjs.org

Slide 32

Slide 32 text

ngAria • Talking about accessibility… • This new module adds ARIA attributes • aria-* • checked, disabled, hidden, invalid…

Slide 33

Slide 33 text

ngAria • So this
 • Becomes this


Slide 34

Slide 34 text

ngStrictDi • (function ($scope) {…}) • (['$scope',
 function ($scope) {…}])

Slide 35

Slide 35 text

ngStrictDi • • Fails on functions without annotation • Incompatible with Batarang
 :(

Slide 36

Slide 36 text

$scope.$watchGroup() • Takes an array and a callback • Watch many properties • Callback - when any of them changes

Slide 37

Slide 37 text

time for more exciting stuff!

Slide 38

Slide 38 text

Forms • Forms in Angular are cool, right? • But yet some things were missing…

Slide 39

Slide 39 text

ngModelOptions • Usecase • Update model value after: • User focuses out of the input • A given time after the last keystroke

Slide 40

Slide 40 text

ngModelOptions {{value1Final}} • Angular 1.2: not that bad;
 additional variable has to be used

Slide 41

Slide 41 text

ngModelOptions {{value1}} • Angular 1.3: same length;
 more clear, no additional variables

Slide 42

Slide 42 text

that was too easy let's update after a timeout too

Slide 43

Slide 43 text

ngModelOptions • Template: {{value2Final}} • Function call on blur!

Slide 44

Slide 44 text

ngModelOptions • Controller: var timer; $scope.onBlur = function () { $timeout.cancel(timer); $scope.value2Final= $scope.value2;
 };

Slide 45

Slide 45 text

ngModelOptions • Controller: $scope.$watch('value2', function () { $timeout.cancel(timer); timer = $timeout(function () { $scope.value2Final = $scope.value2; }, 1000);
 });

Slide 46

Slide 46 text

this is too complicated! what about Angular 1.3?

Slide 47

Slide 47 text

ngModelOptions • Angular 1.3 is all declarative:

Slide 48

Slide 48 text

ngModelOptions • Affects $setViewValue() too! • Pending changes can be cancelled with $rollbackViewValue()

Slide 49

Slide 49 text

Forms validation spoiler: async validators ahead!

Slide 50

Slide 50 text

form validation • All HTML5 validation attributes are now properly bound to ngModel • No need for ng-pattern, ng-minlength, ng-maxlength, although they are still available

Slide 51

Slide 51 text

form validation • Angular 1.2:


Slide 52

Slide 52 text

form validation • Angular 1.3:


Slide 53

Slide 53 text

form validation • There are differences though: • 
 Some browsers disallow any text longer than 13 characters • 
 Only Angular error

Slide 54

Slide 54 text

ngMessages • New directive for displaying validation errors • Makes HTML code cleaner

Slide 55

Slide 55 text

ngMessages • Angular 1.2:
 
 Required
 
 Minlength
 
 Pattern

Slide 56

Slide 56 text

ngMessages • Angular 1.3:


 Required

 Minlength
 Pattern


Slide 57

Slide 57 text

ngMessages • ngMessagesMultiple - display all errors at once • Impossible in Angular 1.2 without hacks

Slide 58

Slide 58 text

ngMessages • ngMessagesInclude - include specified template into container • In 1.2 possible with use of ngInclude and ngIf

Slide 59

Slide 59 text

custom validators • In Angular 1.2 - $parsers and $formatters pipelines • Had to call $setValidity manually • In Angular 1.3 there's a separate pipeline for that

Slide 60

Slide 60 text

custom validators • How? custom directive with
 require: 'ngModel' • Add a function on object
 ngModel.$validators

Slide 61

Slide 61 text

custom validators require: 'ngModel', link: function (_, _, _, ngModel) { ngModel.$validators.three = function (value) { return (value === 3);
 };
 }

Slide 62

Slide 62 text

custom async validators • Long awaited feature! • As simple as the validators pipeline • How? Add a function returning a promise to the pipeline

Slide 63

Slide 63 text

custom async validators require: 'ngModel', link: function (_, _, _, ngModel) { ngModel.$asyncValidators.async = function (value) { return promise; }; }

Slide 64

Slide 64 text

custom async validators • $pending property on the controller while validation is in progress • Async validators are called after all other validators pass

Slide 65

Slide 65 text

$touched • One more small thing • $touched property added next to $dirty, $pristine etc… • It's set to true after user focuses out of an input

Slide 66

Slide 66 text

$touched • We had to simulate that in Angular 1.1 and 1.2 way too many times • This tiny little property makes me personally very happy! :)

Slide 67

Slide 67 text

improved SVG support • ng-repeat inside of SVG now works • You can use templateNamespace: 'svg'
 to create SVG directives

Slide 68

Slide 68 text

improved ng-src support • "/ngPoznan/{{id}}/a.jpg" • Invalid request if id is empty • Won't happen anymore. • Fixed in ng-src, ng-href, ng-srcset

Slide 69

Slide 69 text

improved animations • Added ng-animate-children • Added staggering animations • Meaningful transitions (WiP) • But that's a topic for another presentation…

Slide 70

Slide 70 text

last thing but certainly not least!

Slide 71

Slide 71 text

…drum roll…

Slide 72

Slide 72 text

seriously it's a pretty fascinating feature!

Slide 73

Slide 73 text

one-time bindings you probably all heard about that already

Slide 74

Slide 74 text

one-time binding • New syntax introduced • Expressions that start with :: are one‑time expressions • One-time expressions will not be updated after they are non-undefined

Slide 75

Slide 75 text

one-time binding • It's good for performance - less watches • Can be used everywhere:
 {{::val}}

Slide 76

Slide 76 text

one-time binding • It should be possible to define own syntax for expressions, right? • Well… it is!

Slide 77

Slide 77 text

one-time binding • Angular 1.3 introduces
 $$watchDelegate • Very simple:
 $provide.decorator('$parse', …)

Slide 78

Slide 78 text

(function() {
 var wrap,
 __slice = [].slice;
 
 wrap = function(listener, toDo, invokeAlways, isDefined) {
 return _.wrap(toDo, function() {
 var args, originalFn, value, valueIsDefined;
 originalFn = arguments[0], value = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
 valueIsDefined = isDefined(value);
 if (!invokeAlways && !valueIsDefined) {
 return;
 }
 originalFn.call.apply(originalFn, [this, value].concat(__slice.call(args)));
 if (valueIsDefined) {
 return listener.cleanup();
 }
 });
 };
 
 angular.module('ngWatchWhen', []).constant('ngWatchWhenRegEx', /^\:\:([^\:]+)(\:\:[^\:]+)$/).value('ngWatchWhenCloneExpression', function(getter) {
 var clone;
 clone = function() {
 return getter.apply(this, arguments);
 };
 return _.merge(clone, getter);
 }).config(function($provide) {
 return $provide.decorator('$parse', function($delegate, ngWatchWhenRegEx, ngWatchWhenDelegateFactory, ngWatchWhenCloneExpression) {
 return _.wrap($delegate, function($parse, exp, interceptor) {
 var args, match, onceExp, onceStr, whenExp, whenStr;
 if (angular.isString(exp) && (match = exp.match(ngWatchWhenRegEx))) {
 exp = match[0], whenStr = match[1], onceStr = match[2];
 whenExp = $parse.apply(this, [whenStr]);
 onceExp = ngWatchWhenCloneExpression($parse.apply(this, [onceStr, interceptor]));
 onceExp.$$watchDelegate = ngWatchWhenDelegateFactory(whenExp, onceExp);
 return onceExp;
 } else {
 args = [exp];
 if (interceptor != null) {
 args.push(interceptor);
 }
 return $parse.apply(this, args);
 }
 });
 });
 }).value('ngWatchWhenDelegateFactory', function(whenExp, onceExp) {
 return _.wrap(onceExp.$$watchDelegate, function(originalWatchDelegate, scope, listener, objectEquality, parsedExpression) {
 var onceWatch, registerOnceWatch, whenWatch;
 onceWatch = null;
 registerOnceWatch = function() {
 onceWatch = {};
 onceWatch.deregister = originalWatchDelegate.call(this, scope, listener, objectEquality, parsedExpression);
 return onceWatch.watcher = _.first(scope.$$watchers);
 };
 registerOnceWatch();
 whenWatch = scope.$watch(whenExp, function() {
 if (!_.contains(scope.$$watchers, onceWatch.watcher)) {
 return registerOnceWatch();
 }
 });
 return function() {
 whenWatch();
 if (_.contains(scope.$$watchers, onceWatch.watcher)) {
 return onceWatch.deregister();
 }
 };
 });
 });
 
 }).call(this);

Slide 79

Slide 79 text

one-time binding • But seriously, it's quite complicated. • This simple function was 69 LoC • There are already two (or more?) modules on GitHub doing that!

Slide 80

Slide 80 text

one-time binding • angular-watch-when
 "bind sometimes" • ::myModel::myModel.id
 update myModel.id binding whenever myModel is changed

Slide 81

Slide 81 text

one-time binding • angular-watch-require
 reuse $watch from identical expression • ?model, ^model, ?^model

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

lots of possibilities angular is more flexible than ever

Slide 84

Slide 84 text

the outro

Slide 85

Slide 85 text

AngularJS 1.3 • No IE8 support • Huge performance improvements • Better accessibility (ngAria) • Material Design

Slide 86

Slide 86 text

AngularJS 1.3 • ngModelOptions • Boosted forms and validators (async!) • Improved SVG • Animations on steroids (WiP) • Added one-time binding

Slide 87

Slide 87 text

one more thing “I heard about AngularJS 2.0…”

Slide 88

Slide 88 text

• Don't worry! • Angular 1.3 will be supported for two more years after the release of 2.0! “I heard about AngularJS 2.0…”

Slide 89

Slide 89 text

• 1.3 branch has the new maintainer already: Pete Bacon Darwin took over • Angular creators promised to release a migration guide from 1.x to 2.0 “I heard about AngularJS 2.0…”

Slide 90

Slide 90 text

AngularJS 1.3 is awesome

Slide 91

Slide 91 text

Michał Miszczyszyn Code available at:
 mmiszy.github.io/angular-comparison/ @mmiszy
 [email protected]

Slide 92

Slide 92 text

AngularJS 1.3

Slide 93

Slide 93 text

Thank you!