@@ -13,6 +13,301 @@ which drives many of these changes.
13
13
* Several new features, especially animations, would not be possible without a few changes.
14
14
* Finally, some outstanding bugs were best fixed by changing an existing API.
15
15
16
+ # Migrating from 1.3 to 1.4
17
+
18
+ Angular 1.4 fixes the major animation issues and introduces some breaking changes for `cookies`, `ngMessages`,
19
+ `$compile`, `ngRepeat`, `ngOptions `and some fixes to core filters: `limitTo` and `filter`.
20
+
21
+ The reason for the ngAnimate refactor was to fix timing issues and to expose new APIs to allow
22
+ for developers to construct more versatile animations. We now have access to `$animateCss`
23
+ and the many timing-oriented bugs were fixed which resulted in more smoother animations.
24
+ If animation is something of interest, then please read over the breaking changes below for animations when
25
+ `ngAnimate` is used.
26
+
27
+ ngMessages has also been upgraded to allow for dynamic message resolution. This handy feature allows for developers
28
+ to render error messages with ngMessages that are listed with a directive such as ngRepeat. A great usecase for this
29
+ involves pulling error message data from a server and then displaying that data via the mechanics of ngMessages. Be
30
+ sure to read the breaking change involved with `ngMessagesInclude` to upgrade your template code.
31
+
32
+ Other changes, such as the ordering of elements with ngRepeat and ngOptions, may also effect the behavior of your
33
+ application. And be sure to also read up on the changes to `$cookies`. The migration jump from 1.3 to 1.4 should be
34
+ relatively straightforward otherwise.
35
+
36
+
37
+
38
+
39
+ ## Animation (`ngAnimate`)
40
+
41
+ Animation in 1.4 have been refactored internally and the API has stayed much the same. There are, however,
42
+ some breaking changes that need to be addressed when any Angular animation code is upgraded to work in 1.4.
43
+
44
+ Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
45
+ JavaSript and CSS animations can no longer be run in
46
+ parallel. With earlier versions of ngAnimate, both CSS and JS animations
47
+ would be run together when multiple animations were detected. This
48
+ feature has now been removed, however, the same effect, with even more
49
+ possibilities, can be achieved by injecting `$animateCss` into a
50
+ JavaScript-defined animation and creating custom CSS-based animations
51
+ from there.
52
+
53
+ By using `$animateCss` inside of a JavaScript animation in Angular 1.4, we can trigger custom CSS-based animations
54
+ directly from our JavaScript code.
55
+
56
+ ```js
57
+ ngModule.animation('.slide-animation', ['$animateCss', function($animateCss) {
58
+ return {
59
+ enter: function(element, doneFn) {
60
+ // this will trigger a `.ng-enter` and `.ng-enter-active` CSS animation
61
+ var animation = $animateCss(element, {
62
+ event: 'enter'
63
+ // any other CSS-related properties
64
+ // addClass: 'some-class',
65
+ // removeClass: 'some-other-class',
66
+ // from: {},
67
+ // to: {}
68
+ });
69
+
70
+ // make sure to read the ngAnimate docs to understand how this works
71
+ animation.start().done(doneFn);
72
+ }
73
+ }
74
+ }]);
75
+ ```
76
+
77
+ {@link ngAnimate.$animateCss Click here to learn how to use $animateCss in your animation code}
78
+
79
+ Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
80
+ animation-related callbacks are now fired on `$animate.on` instead of directly being on the element.
81
+
82
+ ```js
83
+ // < 1.4
84
+ element.on('$animate:before', function(e, data) {
85
+ if (data.event === 'enter') { ... }
86
+ });
87
+ element.off('$animate:before', fn);
88
+
89
+ // 1.4+
90
+ $animate.on(element, 'enter', function(data) {
91
+ //...
92
+ });
93
+ $animate.off(element, 'enter', fn);
94
+ ```
95
+
96
+ Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
97
+ the function params for `$animate.enabled()` when an element is used are now flipped. This fix allows
98
+ the function to act as a getter when a single element param is provided.
99
+
100
+ ```js
101
+ // < 1.4
102
+ $animate.enabled(false, element);
103
+
104
+ // 1.4+
105
+ $animate.enabled(element, false);
106
+ ```
107
+
108
+ Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
109
+ in addition to disabling the children of the element, `$animate.enabled(element, false)` will now also
110
+ disable animations on the element itself.
111
+
112
+ Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
113
+ there is no need to call `$scope.$apply` or `$scope.$digest` inside of a animation promise callback anymore
114
+ since the promise is resolved within a digest automatically. (Not to worry, any extra digests will not be
115
+ run unless the promise is used.)
116
+
117
+ ```js
118
+ // < 1.4
119
+ $animate.enter(element).then(function() {
120
+ $scope.$apply(function() {
121
+ $scope.explode = true;
122
+ });
123
+ });
124
+
125
+ // 1.4+
126
+ $animate.enter(element).then(function() {
127
+ $scope.explode = true;
128
+ });
129
+ ```
130
+
131
+ Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
132
+ when an enter, leave or move animation is triggered then it will always end any pending or active parent
133
+ class based animations (animations triggered via ngClass) in order to ensure that any CSS styles are resolved in time.
134
+
135
+
136
+
137
+
138
+ ## Forms (`ngMessages`, `ngOptions`)
139
+
140
+ ### ngMessages
141
+ The ngMessages module has also been subject to an internal refactor to allow the feature to be more flexible
142
+ and compatible with dynamic message data. The ngMessage directive now supports a new attribute called `ng-message-exp`
143
+ which will evaluate an expression and will keep track of that expression as it changes in order to re-evaluate
144
+ the listed messages.
145
+
146
+ There is only one breaking change. Please consider the following when including remote message templates via `ng-messages-include`:
147
+
148
+ Due to [c9a4421f](https://github.com/angular/angular.js/commit/c9a4421fc3c97448527eadef1f42eb2f487ec2e0),
149
+ the `ngMessagesInclude` attribute has now been removed and cannot be used in the same element containing
150
+ the `ngMessages` directive. Instead, `ngMessagesInclude` is to be used on its own element inline with
151
+ other inline messages situated as children within the `ngMessages` container directive.
152
+
153
+ ```html
154
+ <!-- AngularJS 1.3.x -->
155
+ <div ng-messages="model.$error" ng-messages-include="remote.html">
156
+ <div ng-message="required">Your message is required</div>
157
+ </div>
158
+
159
+ <!-- AngularJS 1.4.x -->
160
+ <div ng-messages="model.$error">
161
+ <div ng-message="required">Your message is required</div>
162
+ <div ng-messages-include="remote.html"></div>
163
+ </div>
164
+ ```
165
+
166
+ Depending on where the `ngMessagesInclude` directive is placed it will be prioritized inline with the other messages
167
+ before and after it.
168
+
169
+ ### ngOptions
170
+
171
+ Due to [7fda214c](https://github.com/angular/angular.js/commit/7fda214c4f65a6a06b25cf5d5aff013a364e9cef),
172
+ when `ngOptions` renders the option values within the DOM, the resulting HTML code is different. Normally this
173
+ should not affect your application at all, however, if your code relies on inspecing the value property of `<option>`
174
+ elements (that `ngOptions` generates) then be sure to read the details
175
+ [here](https://github.com/angular/angular.js/commit/7fda214c4f65a6a06b25cf5d5aff013a364e9cef).
176
+
177
+ Due to [7fda214c](https://github.com/angular/angular.js/commit/7fda214c4f65a6a06b25cf5d5aff013a364e9cef),
178
+ when iterating over an object's properties using the `(key, value) in obj` syntax
179
+ the order of the elements used to be sorted alphabetically. This was an artificial
180
+ attempt to create a deterministic ordering since browsers don't guarantee the order.
181
+ But in practice this is not what people want and so this change iterates over properties
182
+ in the order they are returned by Object.keys(obj), which is almost always the order
183
+ in which the properties were defined.
184
+
185
+
186
+
187
+
188
+ ## Templating (`ngRepeat`, `$compile`)
189
+
190
+ ### ngRepeat
191
+
192
+ Due to [c260e738](https://github.com/angular/angular.js/commit/c260e7386391877625eda086480de73e8a0ba921),
193
+ previously, the order of items when using ngRepeat to iterate over object properties was guaranteed to be consistent
194
+ by sorting the keys into alphabetic order.
195
+
196
+ Now, the order of the items is browser dependent based on the order returned
197
+ from iterating over the object using the `for key in obj` syntax.
198
+
199
+ It seems that browsers generally follow the strategy of providing
200
+ keys in the order in which they were defined, although there are exceptions
201
+ when keys are deleted and reinstated. See
202
+ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_issues
203
+
204
+ The best approach is to convert Objects into Arrays by a filter such as
205
+ https://github.com/petebacondarwin/angular-toArrayFilter
206
+ or some other mechanism, and then sort them manually in the order you need.
207
+
208
+
209
+ ### $compile
210
+
211
+ Due to [6a38dbfd](https://github.com/angular/angular.js/commit/6a38dbfd3c34c8f9efff503d17eb3cbeb666d422),
212
+ previously, '&' expressions would always set up a function in the isolate scope. Now, if the binding
213
+ is marked as optional and the attribute is not specified, no function will be added to the isolate scope.
214
+
215
+
216
+
217
+ ## Cookies (`ngCookies`)
218
+
219
+ Due to [38fbe3ee](https://github.com/angular/angular.js/commit/38fbe3ee8370fc449b82d80df07b5c2ed2cd5fbe),
220
+ `$cookies` will no longer expose properties that represent the current browser cookie
221
+ values.
222
+
223
+ The new API on `$cookies` includes:
224
+
225
+ * `get`
226
+ * `put`
227
+ * `getObject`
228
+ * `putObject`
229
+ * `getAll`
230
+ * `remove`
231
+
232
+ The new API no longer polls the browser for changes to the cookies and no longer copy
233
+ cookie values onto the `$cookies` object.
234
+
235
+ The polling is expensive and caused issues with the `$cookies` properties not
236
+ synchronizing correctly with the actual browser cookie values.
237
+
238
+ The reason the polling was originally added was to allow communication between
239
+ different tabs, but there are better ways to do this today (for example `localStorage`).
240
+
241
+ Now you must explictly use the methods above in order to access cookie data. This also means that
242
+ you can no longer watch the any properties on `$cookies` for changes to detect for any changes
243
+ that occur on the browsers cookies.
244
+
245
+ This feature is generally only needed if a 3rd party library was programmatically
246
+ changing the cookies at runtime. If you rely on this then you must either write code that
247
+ can react to the 3rd party library making the changes to cookies or implement your own polling
248
+ mechanism.
249
+
250
+ **DEPRECATION NOTICE**
251
+
252
+ `$cookieStore` is now deprecated as all the useful logic
253
+ has been moved to `$cookies`, to which `$cookieStore` now simply
254
+ delegates calls.
255
+
256
+
257
+
258
+
259
+ ## Server Requests (`$http`)
260
+
261
+ Due to [5da1256](https://github.com/angular/angular.js/commit/5da1256fc2812d5b28fb0af0de81256054856369),
262
+ `transformRequest` functions can no longer modify request headers.
263
+
264
+ Before this commit `transformRequest` could modify request headers, ex.:
265
+
266
+ ```javascript
267
+ function requestTransform(data, headers) {
268
+ headers = angular.extend(headers(), {
269
+ 'X-MY_HEADER': 'abcd'
270
+ });
271
+ }
272
+ return angular.toJson(data);
273
+ }
274
+ ```
275
+
276
+ This behavior was unintended and undocumented, so the change should affect very few applications. If one
277
+ needs to dynamically add / remove headers it should be done in a header function, for example:
278
+
279
+ ```javascript
280
+ $http.get(url, {
281
+ headers: {
282
+ 'X-MY_HEADER': function(config) {
283
+ return 'abcd'; //you've got access to a request config object to specify header value dynamically
284
+ }
285
+ }
286
+ })
287
+ ```
288
+
289
+
290
+
291
+
292
+ ## Filters (`filter`, `limitTo`)
293
+
294
+ ### `filter` filter
295
+ Due to [cea8e751](https://github.com/angular/angular.js/commit/cea8e75144e6910b806b63a6ec2a6d118316fddd),
296
+ the `filter` filter will throw an error when a non array. Beforehand it would silently ignore the error
297
+ and return an empty array. This is not the behavior anymore.
298
+
299
+ If necessary, this can be worked around by converting an object to an array,
300
+ using a filter such as https://github.com/petebacondarwin/angular-toArrayFilter.
301
+
302
+ ### `limitTo` filter
303
+ Due to [a3c3bf33](https://github.com/angular/angular.js/commit/a3c3bf3332e5685dc319c46faef882cb6ac246e1),
304
+ the limitTo filter has changed behavior when the provided limit value is invalid.
305
+ Now, instead of returning empty object/array, it returns unchanged input.
306
+
307
+
308
+
309
+
310
+
16
311
# Migrating from 1.2 to 1.3
17
312
18
313
## Controllers
0 commit comments