angular.js v1.0.0.rc1 Release Notes
Release Date: 2012-03-13 // about 12 years ago-
$compile rewrite
The compiler was completely rewritten from scratch using ideas from this ๐ design document. Please check out the [$compile] and ๐ $compileProvider.directive ๐ docs. The biggest improvements and changes are listed below.
๐ the compiler now transparently supports several directive syntaxes. For example while before there was just one way to use
ng:include
directive:<ng:include src="someSrc"></ng:include>
. The new compiler treats all of the following as equivalent:<ng:include src="someSrc"></ng:include>
<ng-include src="someSrc"></ng-include>
<x-ng-include src="someSrc"></x-ng-include>
<div ng:include src="someSrc"></div>
<div ng-include src="someSrc"></div>
<div data-ng-include src="someSrc"></div>
<div ng:include="someSrc"></div>
<div ng-include="someSrc"></div>
<div data-ng-include="someSrc"></div>
<div class="ng-include: someSrc"></div>
This will give template creators great flexibility to consider the tradeoffs between html code validity and code conciseness and pick the syntax that works the best for them.
๐ we are switching all of our code/docs/examples to use
ng-foo
directive name style instead ofng:foo
. The new compiler doesn't distinguish between these and other name styles (all of them are equally supported), the main difference is thatng-foo
is easier to select with css selectors. Check out the Internet Explorer Compatibility doc to learn about various IE-related requirements for different directive naming styles.๐
angular.directive
,angular.widget
,angular.attrWidget
were merged into a single concept: adirective
which is registered via myModule.directive or $compileProvider.directive. You can control execution priority of multiple directives on the same element (previously the main difference between a attribute widget and a directive) via a directive priority setting.previously the linking functions of directives were called top to bottom following the DOM tree, to enable a linking fn to work child DOM nodes that were already processed by child linking fns the order was changed as follows: compile functions run top to bottom following the DOM tree, but linking functions run bottom-up following the DOM tree. In some rare cases it is desirable for linking fns to be called top to bottom and for these it is possible to register "prelinking" functions (check out the docs for the return value of the compile function).
angular.markup
andangular.attrMarkup
were replaced with interpolation via$interpolate
service.- In the past
{{foo}}
markup was getting translated to<span ng-bind="foo"></span>
during the early stage of template compilation. Addition of this extra node was in some cases undesirable and caused problems. The new compiler with the help of the $interpolate service removes the need for these artificial nodes. - As a side-effect of not using artificial nodes available for all bindings, the
html
filter which used to innerHTML (sanitized) html into the artificial node was converted into a directive. So instead of{{ someRawHtml | html }}
use<div ng-bind-html="someRawHtml"></div>
and instead of{{ someRawHtml | html:"unsafe" }}
use<div ng-bind-html-unsafe="someRawHtml"></div>
. Please check out the ng-bind-html and ng-bind-html-unsafe directive docs. - Custom markup has been used by developers only to switch from
{{ }}
markup to(( ))
or something similar in order to avoid conflicts with server-side templating libraries. We made it easier to do this kind of customization by making the start and end symbol of the interpolation configurable via $interpolateProvider.
- In the past
๐ template loader loads template fragments from script elements and populates the $templateCache with them. Templates loaded in this way can be then used with
ng-include
,ng-view
as well as directive templates (see thetemplateUrl
property of the directive config object).
Forms / input controls / two-way data binding
The implementation of forms and input bindings was modified to address issues around composability, ease of adding custom validation and formatting. Please check out the ๐ forms dev guide article to learn about forms, form control bindings and input validation. The biggest changes are listed below.
๐ any directive can add formatter/parser (validators, convertors) to an input type. This allows better composability of input types with custom validators and formatters. So instead of creating new custom input type for everything, it's now possible to take existing input type and add an additional formatter and/or validator to it via a custom directive.
0๏ธโฃ inputs propagates changes only on the blur event by default (use new
ng-model-instant
directive if you want to propagate changes on each keystroke).no more custom input types, use directives to customize existing types.
โ removed $formFactory.
โ removed parallel scope hierarchy (forms, widgets).
โ removed
list
input type (useng-list
directive instead).โ removed integer input type.
Controller-scope separation
Controllers are now standalone objects, created using the "new" operator, and not mixed with scope object anymore. This addresses many issues including: #321 and #425.
๐ The design doc explains the reasoning for this major change and how it solves many issues.
Before:
function MyCtrl() { var self = this;
this.model = 'some model of any type';
this.fnUsedFromTemplate = function() { someApiThatTakesCallback(function callbackFn() { self.model = 'updatedModel'; }); }; }
After:
function MyCtrl($scope) { $scope.model = 'some model of any type';
$scope.fnUsedFromTemplate = function() { someApiThatTakesCallback(function() { $scope.model = 'updatedModel'; }); } }
Temporary backwards compatibility: Load the following module in your app to recreate the previous behavior and migrate your controllers one at a time: https://gist.github.com/1649788
$route service changes
๐ง As advertised in the past we moved the $route configuration from the run phase of the application to the config phase. This means that instead of defining routes via
$route.when
/$route.otherwise
you should use$routeProvider.when
/$routeProvider.otherwise
instead.route scope is now being created by the
ng-view
rather than by$route
, this resolved many issues we've previously faced. For more info, read the commit message.โ removed
$route.parent()
- it's unnecessary because the scope is properly created in the scope hierarchy byng-view
.๐ new
$viewContentLoaded
and$includeContentLoaded
events which directives can use to be notified when a template content is (re)loaded.ng-view
now hasonload
attribute which behaves similarly to the one onng-include
.
Directives
- ๐
ng-model
binding on select[multiple] element should support binding to an array (commit) - event object is now accessible as
$event
inng-click
and other directives (commit, issue #259 - ๐
ng-class
directive now support map of classnames and conditions e.g.<div ng-class="{'hide': !visible, 'warning': isAlert()}"...
(contributed by Kai Groner) (commit)
Scope changes
scope.$emit
/$broadcast
return the event object, add cancelled property (commit)scope.$new()
takes one argument - a boolean indicating if the newly-created child scope should be isolated (not prototypically inheriting from the current scope). Previously the first argument was reference to the controller constructor, but because of the scope/controller separation the controllers should be instantiated via the$controller
service. (commit)fn signature change for change listener functions registered via
scope.$watch
- this means that the scope object can be listed in the arguments list only if it's needed and skipped otherwise. (commit)- before:
scope.$watch('someModel', function(scope, newVal, oldVal) {})
- after:
scope.$watch('someModel', function(newVal, oldVal, scope) {})
- before:
scope.$watch
now compares object by reference and only if extra boolean flag is passed comparison by equality is used. This was done to avoid unintended performance issues. (commit)- before:
scope.$watch('expression', function(scope, newVal, oldVal) {})
- after:
scope.$watch('expression', function(newVal, oldVal, scope) {}, true)
- before:
scope.$destroy
doesn't cause the$destroy
event to be emitted any more - this event was primarily used by the old forms implementation and is not needed any more. We are considering broadcasting this event in the future, which could then be used by directives and child scopes to be notified of their scope destruction.
๐ New directives:
- ๐ ng-mouseleave
- ๐ ng-mousemove
- ๐ ng-mouseover
- ๐ ng-mouseup
- ๐ ng-mousedown
- ๐ ng-dblclick
- ๐ ng-model-instant
$injector / modules
$injector.instantiate
should return the object returned from constructor if one was returned (commit)- ๐
$injector.instantiate
should support array annotations for Type argument (e.g. instantiate(['dep1', 'dep2', Type])) (commit) - quickly fail if circular dependencies are detected during instantiation (commit)
- โ added $provide.constant to enable registration of constants that are available in both the config and run phase (commit)
$provide.service
was renamed to $provide.provider (commit)$provide.service
takes a constructor fn and creates a service instance by using $injector.instantiate
๐ New services:
- ๐ $sanitize
- ๐ $interpolate
jqLite (angular.element)
- โ added
contents()
(commit) - โ added
wrap()
(commit) - ๐ fix memory leaking in IE8 (remove monkey patched methods on Event) (commit, commit)
๐ Docs
- ๐ new Modules dev guide article
๐ Small bug fixes
- ๐ fix incorrect comparison of dates by angular.equals (commit)
- ๐
scope.$watch
support watching functions (commit, commit) $http
should not json-serialize File objects, instead just send them raw (commit)- ๐
$compile
should ignore content of style and script elements (commit, commit) TzDate#getDay()
should take into account the timezone offset (contributed by Stephane Bisson) (commit)
Small features
- ๐
$parse
service now supports local vars in expressions (commit)