| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | # Lifecycle Hooks
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | A component has a lifecycle managed by Angular. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Angular creates it, renders it, creates and renders its children, | 
					
						
							|  |  |  | checks it when its data-bound properties change, and destroys it before removing it from the DOM. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Angular offers **lifecycle hooks** | 
					
						
							|  |  |  | that provide visibility into these key life moments and the ability to act when they occur. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 09:54:35 -07:00
										 |  |  | A directive has the same set of lifecycle hooks. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | {@a hooks-overview} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Component lifecycle hooks overview
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Directive and component instances have a lifecycle | 
					
						
							|  |  |  | as Angular creates, updates, and destroys them. | 
					
						
							|  |  |  | Developers can tap into key moments in that lifecycle by implementing | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | one or more of the *lifecycle hook* interfaces in the Angular `core` library. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Each interface has a single hook method whose name is the interface name prefixed with `ng`. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | For example, the `OnInit` interface has a hook method named `ngOnInit()` | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | that Angular calls shortly after creating the component: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/peek-a-boo.component.ts" region="ngOnInit" title="peek-a-boo.component.ts (excerpt)" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 09:54:35 -07:00
										 |  |  | No directive or component will implement all of the lifecycle hooks. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Angular only calls a directive/component hook method *if it is defined*. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a hooks-purpose-timing} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Lifecycle sequence
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | *After* creating a component/directive by calling its constructor, Angular | 
					
						
							|  |  |  | calls the lifecycle hook methods in the following sequence at specific moments: | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | <table width="100%"> | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   <col width="20%"></col> | 
					
						
							|  |  |  |   <col width="80%"></col> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   <tr> | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |     <th>Hook</th> | 
					
						
							|  |  |  |     <th>Purpose and Timing</th> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |       <code>ngOnChanges()</code> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Respond when Angular (re)sets data-bound input properties. | 
					
						
							|  |  |  |       The method receives a `SimpleChanges` object of current and previous property values. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Called before `ngOnInit()` and whenever one or more data-bound input properties change. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |       <code>ngOnInit()</code> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Initialize the directive/component after Angular first displays the data-bound properties | 
					
						
							|  |  |  |       and sets the directive/component's input properties. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Called _once_, after the _first_ `ngOnChanges()`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |       <code>ngDoCheck()</code> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Detect and act upon changes that Angular can't or won't detect on its own. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Called during every change detection run, immediately after `ngOnChanges()` and `ngOnInit()`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |       <code>ngAfterContentInit()</code> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 09:54:35 -07:00
										 |  |  |       Respond after Angular projects external content into the component's view / the view that a directive is in. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Called _once_ after the first `ngDoCheck()`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |       <code>ngAfterContentChecked()</code> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 09:54:35 -07:00
										 |  |  |       Respond after Angular checks the content projected into the directive/component. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Called after the `ngAfterContentInit()` and every subsequent `ngDoCheck()`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |       <code>ngAfterViewInit()</code> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 09:54:35 -07:00
										 |  |  |       Respond after Angular initializes the component's views and child views / the view that a directive is in. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Called _once_ after the first `ngAfterContentChecked()`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |       <code>ngAfterViewChecked()</code> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 09:54:35 -07:00
										 |  |  |       Respond after Angular checks the component's views and child views / the view that a directive is in. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Called after the `ngAfterViewInit` and every subsequent `ngAfterContentChecked()`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-12-17 14:17:43 +02:00
										 |  |  |       <code>ngOnDestroy()</code> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Cleanup just before Angular destroys the directive/component. | 
					
						
							|  |  |  |       Unsubscribe Observables and detach event handlers to avoid memory leaks. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Called _just before_ Angular destroys the directive/component. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |   </tr> | 
					
						
							|  |  |  | </table> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | {@a interface-optional} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | ## Interfaces are optional (technically)
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | The interfaces are optional for JavaScript and Typescript developers from a purely technical perspective. | 
					
						
							|  |  |  | The JavaScript language doesn't have interfaces. | 
					
						
							|  |  |  | Angular can't see TypeScript interfaces at runtime because they disappear from the transpiled JavaScript. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Fortunately, they aren't necessary. | 
					
						
							|  |  |  | You don't have to add the lifecycle hook interfaces to directives and components to benefit from the hooks themselves. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Angular instead inspects directive and component classes and calls the hook methods *if they are defined*. | 
					
						
							|  |  |  | Angular finds and calls methods like `ngOnInit()`, with or without the interfaces. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Nonetheless, it's good practice to add interfaces to TypeScript directive classes | 
					
						
							|  |  |  | in order to benefit from strong typing and editor tooling. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | {@a other-lifecycle-hooks} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Other Angular lifecycle hooks
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Other Angular sub-systems may have their own lifecycle hooks apart from these component hooks. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 3rd party libraries might implement their hooks as well in order to give developers more | 
					
						
							|  |  |  | control over how these libraries are used. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | {@a the-sample} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## Lifecycle examples
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The <live-example></live-example> | 
					
						
							|  |  |  | demonstrates the lifecycle hooks in action through a series of exercises | 
					
						
							|  |  |  | presented as components under the control of the root `AppComponent`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | They follow a common pattern: a *parent* component serves as a test rig for | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | a *child* component that illustrates one or more of the lifecycle hook methods. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Here's a brief description of each exercise: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <table width="100%"> | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   <col width="20%"></col> | 
					
						
							|  |  |  |   <col width="80%"></col> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   <tr> | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |     <th>Component</th> | 
					
						
							|  |  |  |     <th>Description</th> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							|  |  |  |       <a href="#peek-a-boo">Peek-a-boo</a> | 
					
						
							|  |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Demonstrates every lifecycle hook. | 
					
						
							|  |  |  |       Each hook method writes to the on-screen log. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |     </td> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							|  |  |  |       <a href="#spy">Spy</a> | 
					
						
							|  |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Directives have lifecycle hooks too. | 
					
						
							|  |  |  |       A `SpyDirective` can log when the element it spies upon is | 
					
						
							|  |  |  |       created or destroyed using the `ngOnInit` and `ngOnDestroy` hooks. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       This example applies the `SpyDirective` to a `<div>` in an `ngFor` *hero* repeater | 
					
						
							|  |  |  |       managed by the parent `SpyComponent`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |     </td> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							|  |  |  |       <a href="#onchanges">OnChanges</a> | 
					
						
							|  |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       See how Angular calls the `ngOnChanges()` hook with a `changes` object | 
					
						
							|  |  |  |       every time one of the component input properties changes. | 
					
						
							|  |  |  |       Shows how to interpret the `changes` object. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |     </td> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							|  |  |  |       <a href="#docheck">DoCheck</a> | 
					
						
							|  |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Implements an `ngDoCheck()` method with custom change detection. | 
					
						
							|  |  |  |       See how often Angular calls this hook and watch it post changes to a log. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |     </td> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							|  |  |  |       <a href="#afterview">AfterView</a> | 
					
						
							|  |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Shows what Angular means by a *view*. | 
					
						
							|  |  |  |       Demonstrates the `ngAfterViewInit` and `ngAfterViewChecked` hooks. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |     </td> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							|  |  |  |       <a href="#aftercontent">AfterContent</a> | 
					
						
							|  |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Shows how to project external content into a component and | 
					
						
							|  |  |  |       how to distinguish projected content from a component's view children. | 
					
						
							|  |  |  |       Demonstrates the `ngAfterContentInit` and `ngAfterContentChecked` hooks. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |     </td> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   </tr> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |   <tr style='vertical-align:top'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     <td> | 
					
						
							|  |  |  |       Counter | 
					
						
							|  |  |  |     </td> | 
					
						
							|  |  |  |     <td> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Demonstrates a combination of a component and a directive | 
					
						
							|  |  |  |       each with its own hooks. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       In this example, a `CounterComponent` logs a change (via `ngOnChanges`) | 
					
						
							|  |  |  |       every time the parent component increments its input counter property. | 
					
						
							|  |  |  |       Meanwhile, the `SpyDirective` from the previous example is applied | 
					
						
							|  |  |  |       to the `CounterComponent` log where it watches log entries being created and destroyed. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     </td> | 
					
						
							|  |  |  |   </tr> | 
					
						
							|  |  |  | </table> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The remainder of this page discusses selected exercises in further detail. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | {@a peek-a-boo} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Peek-a-boo: all hooks
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The `PeekABooComponent` demonstrates all of the hooks in one component. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You would rarely, if ever, implement all of the interfaces like this. | 
					
						
							|  |  |  | The peek-a-boo exists to show how Angular calls the hooks in the expected order. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This snapshot reflects the state of the log after the user clicked the *Create...* button and then the *Destroy...* button. | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src="generated/images/guide/lifecycle-hooks/peek-a-boo.png" alt="Peek-a-boo"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The sequence of log messages follows the prescribed hook calling order: | 
					
						
							|  |  |  | `OnChanges`, `OnInit`, `DoCheck` (3x), `AfterContentInit`, `AfterContentChecked` (3x), | 
					
						
							|  |  |  | `AfterViewInit`, `AfterViewChecked` (3x), and `OnDestroy`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   The constructor isn't an Angular hook *per se*. | 
					
						
							|  |  |  |   The log confirms that input properties (the `name` property in this case) have no assigned values at construction. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Had the user clicked the *Update Hero* button, the log would show another `OnChanges` and two more triplets of | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | `DoCheck`, `AfterContentChecked` and `AfterViewChecked`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Clearly these three hooks fire *often*. Keep the logic in these hooks as lean as possible! | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The next examples focus on hook details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a spy} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Spying *OnInit* and *OnDestroy*
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Go undercover with these two spy hooks to discover when an element is initialized or destroyed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is the perfect infiltration job for a directive. | 
					
						
							|  |  |  | The heroes will never know they're being watched. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   Kidding aside, pay attention to two key points: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   1. Angular calls hook methods for *directives* as well as components.<br><br> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   2. A spy directive can provide insight into a DOM object that you cannot change directly. | 
					
						
							|  |  |  |   Obviously you can't touch the implementation of a native `<div>`. | 
					
						
							|  |  |  |   You can't modify a third party component either. | 
					
						
							|  |  |  |   But you can watch both with a directive. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | The sneaky spy directive is simple, consisting almost entirely of `ngOnInit()` and `ngOnDestroy()` hooks | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | that log messages to the parent via an injected `LoggerService`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/spy.directive.ts" region="spy-directive" title="src/app/spy.directive.ts" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | You can apply the spy to any native or component element and it'll be initialized and destroyed | 
					
						
							|  |  |  | at the same time as that element. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Here it is attached to the repeated hero `<div>`: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/spy.component.html" region="template" title="src/app/spy.component.html" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Each spy's birth and death marks the birth and death of the attached hero `<div>` | 
					
						
							|  |  |  | with an entry in the *Hook Log* as seen here: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/lifecycle-hooks/spy-directive.gif' alt="Spy Directive"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Adding a hero results in a new hero `<div>`. The spy's `ngOnInit()` logs that event. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The *Reset* button clears the `heroes` list. | 
					
						
							|  |  |  | Angular removes all hero `<div>` elements from the DOM and destroys their spy directives at the same time. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The spy's `ngOnDestroy()` method reports its last moments. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The `ngOnInit()` and `ngOnDestroy()` methods have more vital roles to play in real applications. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | {@a oninit} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ### _OnInit()_
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Use `ngOnInit()` for two main reasons: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 1. To perform complex initializations shortly after construction. | 
					
						
							|  |  |  | 1. To set up the component after Angular sets the input properties. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Experienced developers agree that components should be cheap and safe to construct. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   Misko Hevery, Angular team lead, | 
					
						
							|  |  |  |   [explains why](http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/) | 
					
						
							|  |  |  |   you should avoid complex constructor logic. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Don't fetch data in a component constructor. | 
					
						
							|  |  |  | You shouldn't worry that a new component will try to contact a remote server when | 
					
						
							|  |  |  | created under test or before you decide to display it. | 
					
						
							|  |  |  | Constructors should do no more than set the initial local variables to simple values. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | An `ngOnInit()` is a good place for a component to fetch its initial data. The | 
					
						
							| 
									
										
										
										
											2017-07-16 11:32:22 +01:00
										 |  |  | [Tour of Heroes Tutorial](tutorial/toh-pt4#oninit) guide shows how. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Remember also that a directive's data-bound input properties are not set until _after construction_. | 
					
						
							|  |  |  | That's a problem if you need to initialize the directive based on those properties. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | They'll have been set when `ngOnInit()` runs. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   The `ngOnChanges()` method is your first opportunity to access those properties. | 
					
						
							|  |  |  |   Angular calls `ngOnChanges()` before `ngOnInit()` and many times after that. | 
					
						
							|  |  |  |   It only calls `ngOnInit()` once. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | You can count on Angular to call the `ngOnInit()` method _soon_ after creating the component. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | That's where the heavy initialization logic belongs. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | {@a ondestroy} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ### _OnDestroy()_
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Put cleanup logic in `ngOnDestroy()`, the logic that *must* run before Angular destroys the directive. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | This is the time to notify another part of the application that the component is going away. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is the place to free resources that won't be garbage collected automatically. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Unsubscribe from Observables and DOM events. Stop interval timers. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Unregister all callbacks that this directive registered with global or application services. | 
					
						
							|  |  |  | You risk memory leaks if you neglect to do so. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | {@a onchanges} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## _OnChanges()_
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Angular calls its `ngOnChanges()` method whenever it detects changes to ***input properties*** of the component (or directive). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | This example monitors the `OnChanges` hook. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/on-changes.component.ts" region="ng-on-changes" title="on-changes.component.ts (excerpt)" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The `ngOnChanges()` method takes an object that maps each changed property name to a | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [SimpleChange](api/core/SimpleChange) object holding the current and previous property values. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | This hook iterates over the changed properties and logs them. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The example component, `OnChangesComponent`, has two input properties: `hero` and `power`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/on-changes.component.ts" region="inputs" title="src/app/on-changes.component.ts" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The host `OnChangesParentComponent` binds to them like this: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/on-changes-parent.component.html" region="on-changes" title="src/app/on-changes-parent.component.html"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Here's the sample in action as the user makes changes. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/lifecycle-hooks/on-changes-anim.gif' alt="OnChanges"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | The log entries appear as the string value of the *power* property changes. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | But the `ngOnChanges` does not catch changes to `hero.name` | 
					
						
							|  |  |  | That's surprising at first. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Angular only calls the hook when the value of the input property changes. | 
					
						
							|  |  |  | The value of the `hero` property is the *reference to the hero object*. | 
					
						
							|  |  |  | Angular doesn't care that the hero's own `name` property changed. | 
					
						
							|  |  |  | The hero object *reference* didn't change so, from Angular's perspective, there is no change to report! | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | {@a docheck} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ## _DoCheck()_
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Use the `DoCheck` hook to detect and act upon changes that Angular doesn't catch on its own. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   Use this method to detect a change that Angular overlooked. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The *DoCheck* sample extends the *OnChanges* sample with the following `ngDoCheck()` hook: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/do-check.component.ts" region="ng-do-check" title="DoCheckComponent (ngDoCheck)" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | This code inspects certain _values of interest_, capturing and comparing their current state against previous values. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | It writes a special message to the log when there are no substantive changes to the `hero` or the `power` | 
					
						
							|  |  |  | so you can see how often `DoCheck` is called. The results are illuminating: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/lifecycle-hooks/do-check-anim.gif' alt="DoCheck"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | While the `ngDoCheck()` hook can detect when the hero's `name` has changed, it has a frightful cost. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | This hook is called with enormous frequency—after _every_ | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | change detection cycle no matter where the change occurred. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | It's called over twenty times in this example before the user can do anything. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Most of these initial checks are triggered by Angular's first rendering of *unrelated data elsewhere on the page*. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Mere mousing into another `<input>` triggers a call. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Relatively few calls reveal actual changes to pertinent data. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Clearly our implementation must be very lightweight or the user experience suffers. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a afterview} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## AfterView
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The *AfterView* sample explores the `AfterViewInit()` and `AfterViewChecked()` hooks that Angular calls | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | *after* it creates a component's child views. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Here's a child view that displays a hero's name in an `<input>`: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="child-view" title="ChildComponent" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The `AfterViewComponent` displays this child view *within its template*: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="template" title="AfterViewComponent (template)" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The following hooks take action based on changing values *within the child view*, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | which can only be reached by querying for the child view via the property decorated with | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [@ViewChild](api/core/ViewChild). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="hooks" title="AfterViewComponent (class excerpts)" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | {@a wait-a-tick} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ### Abide by the unidirectional data flow rule
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The `doSomething()` method updates the screen when the hero name exceeds 10 characters. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/after-view.component.ts" region="do-something" title="AfterViewComponent (doSomething)" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Why does the `doSomething()` method wait a tick before updating `comment`? | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Angular's unidirectional data flow rule forbids updates to the view *after* it has been composed. | 
					
						
							|  |  |  | Both of these hooks fire _after_ the component's view has been composed. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Angular throws an error if the hook updates the component's data-bound `comment` property immediately (try it!). | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | The `LoggerService.tick_then()` postpones the log update | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | for one turn of the browser's JavaScript cycle and that's just long enough. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Here's *AfterView* in action: | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/lifecycle-hooks/after-view-anim.gif' alt="AfterView"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Notice that Angular frequently calls `AfterViewChecked()`, often when there are no changes of interest. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Write lean hook methods to avoid performance problems. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | {@a aftercontent} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## AfterContent
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The *AfterContent* sample explores the `AfterContentInit()` and `AfterContentChecked()` hooks that Angular calls | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | *after* Angular projects external content into the component. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | {@a content-projection} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ### Content projection
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | *Content projection* is a way to import HTML content from outside the component and insert that content | 
					
						
							|  |  |  | into the component's template in a designated spot. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   AngularJS developers know this technique as *transclusion*. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | Consider this variation on the [previous _AfterView_](guide/lifecycle-hooks#afterview) example. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | This time, instead of including the child view within the template, it imports the content from | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | the `AfterContentComponent`'s parent. Here's the parent's template: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="parent-template" title="AfterContentParentComponent (template excerpt)" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-30 14:34:27 +03:00
										 |  |  | Notice that the `<app-child>` tag is tucked between the `<after-content>` tags. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Never put content between a component's element tags *unless you intend to project that content | 
					
						
							|  |  |  | into the component*. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Now look at the component's template: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="template" title="AfterContentComponent (template)" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The `<ng-content>` tag is a *placeholder* for the external content. | 
					
						
							|  |  |  | It tells Angular where to insert that content. | 
					
						
							| 
									
										
										
										
											2018-04-30 14:34:27 +03:00
										 |  |  | In this case, the projected content is the `<app-child>` from the parent. | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/lifecycle-hooks/projected-child-view.png' alt="Projected Content"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  |   The telltale signs of *content projection* are twofold: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   * HTML between component element tags. | 
					
						
							|  |  |  |   * The presence of `<ng-content>` tags in the component's template. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | {@a aftercontent-hooks} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ### AfterContent hooks
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | *AfterContent* hooks are similar to the *AfterView* hooks. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The key difference is in the child component. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | * The *AfterView* hooks concern `ViewChildren`, the child components whose element tags | 
					
						
							|  |  |  | appear *within* the component's template. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * The *AfterContent* hooks concern `ContentChildren`, the child components that Angular | 
					
						
							|  |  |  | projected into the component. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The following *AfterContent* hooks take action based on changing values in a *content child*, | 
					
						
							|  |  |  | which can only be reached by querying for them via the property decorated with | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [@ContentChild](api/core/ContentChild). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 21:31:27 +01:00
										 |  |  | <code-example path="lifecycle-hooks/src/app/after-content.component.ts" region="hooks" title="AfterContentComponent (class excerpts)" linenums="false"></code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | {@a no-unidirectional-flow-worries} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | ### No unidirectional flow worries with _AfterContent_
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | This component's `doSomething()` method update's the component's data-bound `comment` property immediately. | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | There's no [need to wait](guide/lifecycle-hooks#wait-a-tick). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Recall that Angular calls both *AfterContent* hooks before calling either of the *AfterView* hooks. | 
					
						
							|  |  |  | Angular completes composition of the projected content *before* finishing the composition of this component's view. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | There is a small window between the `AfterContent...` and `AfterView...` hooks to modify the host view. |