AngularJS: Did you know…? From 1.0 to 1.3, part 2

Szymon Kosno
4 min readNov 3, 2015

--

This is a continuation of “AngularJS: Did you know…? From 1.0 to 1.3, part 1” focusing on functionalities made available around version 1.0–1.3. I will follow up in another post focusing on changes introduced somewhere between 1.3–1.4.

DISCLAIMER! This is not a change log or tutorial — it is just a list of features that might have been overlooked when working with Angular.

What features were introduced?

26. ngModel now has $validators pipeline (instead of using $formatters and $parsers pipelines to run validation code..)

require: ‘ngModel’,
link: function(scope, elm, attrs, ctrl) {
if (ctrl && ctrl.$validators.email) {
// this will overwrite the default Angular email validator
ctrl.$validators.email = function(modelValue, viewValue) {
return ctrl.$isEmpty(modelValue) ||
EMAIL_REGEXP.test(modelValue);
};
}
}

27. ngModel now has $asyncValidators processed after sync validators

require: ‘ngModel’,
link: function(scope, elm, attrs, ctrl) {
var usernames = [‘Jim’, ‘John’, ‘Jill’, ‘Jackie’];
ctrl.$asyncValidators.username = function(modelValue, viewValue) {

return promise;
};
}

28. When using $scope.$new you can now pass second parameter that will become the new scope’s parent

var isolated = $scope.$new(true);
var other = $scope.$new(false, isolated);

29. $anchorScroll supports a configurable vertical scroll offset

.run([‘$anchorScroll’, function($anchorScroll) {
$anchorScroll.yOffset = 50; // always scroll by 50 extra pixels
}])

30. You can use “*” in scope binding to force $watchCollection instead of $watch (directives)

scope: { prop: '=*' }

31. ngMaxlength (and maxlength) can be set to “-1” effectively disabling this check

32. Currency filter has fractionSize as optional parameter

33. ngModelController now exposes $setDirty function

34. Json filter accepts custom indentation by passing number of spaces

35. You can use camel cased attributes with ng-attr using snake case like “ng-attr-view_box” will become attribute “viewBox”

36. You can now pass context to $evalAsync execution

$rootScope.log = ‘’;
$rootScope.$evalAsync(‘log = log + a’, {a: 1});
$rootScope.$digest();
expect($rootScope.log).toBe(‘1’);

37. Falsy vales changed in expressions

  • values ‘f’, ‘0’, ‘false’, ‘no’, ’n’, ‘[]’ are no longer treated as falsy
  • only JavaScript falsy values are now treated as falsy by the expression parser; there are six of them: false, null, undefined, NaN, 0 and “”

38. $controller no longer looks for controllers on “window” object = global functions no longer are detected as controllers

39. You can NO LONGER use .bind, .call or .apply in expressions

scope.$eval(‘$eval.bind()’)

40. Angular.copy applies the prototype of the original object to the copied object instead of just copying everything from prototype to instance

41. You can NO LONGER access the isolated scope from attributes on the element where the isolated directive is defined!

<isolated-directive some-attribute=”variableFromDirectiveScope”></isolated-directive>

42. ng-pattern now accepts proper regular expressions — if string is given it will be matched literally

//before you could pass and ‘/i’ would be used as flag
this.exp = ‘/abc/i’;
//now please use proper regular expression
this.exp = /abc/i;

43. $cancelUpdate is now called $rollbackViewValue() and used to Cancel an update and reset the input element’s value to prevent an update to the $modelValue

44. Do not use directive “replace” as it is DEPRECATED

45. Additional watch — $watchGroup() that takes array of expressions to watch

46. Major update: ONE-TIME bindings — you can use them in any expression by using “::” in front of variable that you bind

<! — Markup: expression will not change once set 
<h1>{{::title | uppercase}}<h1>
<h1>{{::getTitle()}}</h1>
<div style=”color: {{::color}}”>{{::content}}</div>
<! — within a directive
<qrcode code=”::code”></qrcode>
<ul>
<li ng-repeat=”item in ::items”>{{item.name}}</li>
</ul>

47. Filters NO LONGER run if input did not change! So any injected data change will not re-render filter binding, unless you do

filter.$stateful = true

48. ngAria introduced — accessibility helper for angular directive

49. ngMessages introduced — for easier reuse of error messages in forms (more modifications in 1.4)

50. ngHint introduced — to give you useful hints about Angular coding practices

See you next time — end of part 2

This post concludes list of “did you know” for versions 1.0–1.3. As always I urge you to read full AngularJS change log to always be up-to-date:

https://github.com/angular/angular.js/blob/master/CHANGELOG.md

If you have not seen it I also recommend reviewing part 1 of this post:

I will update this post with link to next one focused on changes done somewhere between 1.3 and 1.4.

--

--

Szymon Kosno

Technical Program Manager at Google, Developer most of the time unless trying to meditate