| 
									
										
										
										
											2014-12-08 14:29:04 -08:00
										 |  |  | # Zones
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A Zone is an execution context that persists across async tasks. You can think of it as thread-local storage for | 
					
						
							| 
									
										
										
										
											2015-03-08 15:35:41 -04:00
										 |  |  | JavaScript. Zones are used to intercept all async operation callbacks in the browser. By intercepting async | 
					
						
							|  |  |  | callbacks Angular can automatically execute the change detection at the end of the VM turn to update the application | 
					
						
							| 
									
										
										
										
											2014-12-08 14:29:04 -08:00
										 |  |  | UI bindings. Zones means that in Angular v2 you don't have to remember to call `rootScope.$apply()` in your async call. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Execution Context
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-05-14 17:21:43 +02:00
										 |  |  | zone.inTheZone = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | zone.fork().run(function () { | 
					
						
							|  |  |  |   zone.inTheZone = true; | 
					
						
							| 
									
										
										
										
											2014-12-08 14:29:04 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   setTimeout(function () { | 
					
						
							| 
									
										
										
										
											2015-05-14 17:21:43 +02:00
										 |  |  |     console.log('async in the zone: ' + zone.inTheZone); | 
					
						
							| 
									
										
										
										
											2014-12-08 14:29:04 -08:00
										 |  |  |   }, 0); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 17:21:43 +02:00
										 |  |  | console.log('sync in the zone: ' + zone.inTheZone); | 
					
						
							| 
									
										
										
										
											2014-12-08 14:29:04 -08:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The above will log: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | sync in the zone: false | 
					
						
							|  |  |  | async in the zone: true | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In the above example the `zone` is a global-callback-local variable. To the `zone`  we can attach arbitrary properties | 
					
						
							|  |  |  | such as `inTheZone`.  When we enter the zone, we get a new `zone` context (which inherits all properties from the | 
					
						
							|  |  |  | parent zone), once we leave the zone, the previous `zone` variable is restored. The key part is that when a async | 
					
						
							|  |  |  | callback is scheduled in the zone, as is the case with `setTimeout`, the current `zone` variable is captured and | 
					
						
							|  |  |  | restored on the callback. This is why the output of the `inTheZone` property inside the callback of the `setTimeout` | 
					
						
							|  |  |  | prints `true`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Callback Interception
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In addition to storing properties on the current `zone`, zones can also allow us to intercept all async callbacks | 
					
						
							|  |  |  | and notify us before and after the callback executes. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | zone.fork({ | 
					
						
							|  |  |  |   afterTask: function () { | 
					
						
							|  |  |  |     // do some cleanup | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }).run(function () { | 
					
						
							|  |  |  |   // do stuff | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The above example will execute the `afterTask` function not only after the `run` finishes, but also after any callback | 
					
						
							|  |  |  | execution which was registered in the `run` block. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Putting it all together in Angular
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-08 15:35:41 -04:00
										 |  |  | In Angular2 it is not necessary to notify Angular of changes manually after async callback, because a relevant | 
					
						
							|  |  |  | async callbacks are intercepted. The question is how do we know which callbacks are Angular relevant? | 
					
						
							| 
									
										
										
										
											2014-12-08 14:29:04 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-14 17:21:43 +02:00
										 |  |  | // TODO(vicb): outdated, rework. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-08 14:29:04 -08:00
										 |  |  | ``` | 
					
						
							|  |  |  | /// Some other code running on page can do async operation | 
					
						
							|  |  |  | document.addEventListener('mousemove', function () { | 
					
						
							|  |  |  |   console.log('Mouse moved.'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var AngularZone = { | 
					
						
							|  |  |  |   afterTask: function () { | 
					
						
							|  |  |  |     console.log('ANGULAR AUTO-DIGEST!'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ngZone = zone.fork(AngularZone); | 
					
						
							|  |  |  | ngZone.run(function() { | 
					
						
							|  |  |  |   console.log('I aware of angular, I should cause digest.'); | 
					
						
							|  |  |  |   document.addEventListener('click', function () { | 
					
						
							|  |  |  |     console.log('Mouse clicked.'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Will produce: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | I aware of angular, I should cause digest. | 
					
						
							|  |  |  | ANGULAR AUTO-DIGEST! | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Moving the mouse will produce many: | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | Mouse moved. | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | But clicking will produce: | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | Mouse clicked. | 
					
						
							|  |  |  | ANGULAR AUTO-DIGEST! | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-08 15:35:41 -04:00
										 |  |  | Notice how the place where the listener was registered will effect whether or not Angular will be notified of the | 
					
						
							| 
									
										
										
										
											2014-12-08 14:29:04 -08:00
										 |  |  | async call and cause a change detection to run to update the UI. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Being able to globally intercept the async operation is important to have a seamless integration with all existing | 
					
						
							| 
									
										
										
										
											2015-03-08 15:35:41 -04:00
										 |  |  | libraries. But it is equally important to be able to differentiate between Angular and non-Angular code running | 
					
						
							| 
									
										
										
										
											2014-12-08 14:29:04 -08:00
										 |  |  | on the same page concurrently. |