docs(lifecycle-hooks): copy edits and update TOC (#3380)
This commit is contained in:
		
							parent
							
								
									82b490f44e
								
							
						
					
					
						commit
						2d61df1c27
					
				| @ -7,7 +7,7 @@ figure | |||||||
|   img(src="/resources/images/devguide/lifecycle-hooks/hooks-in-sequence.png" alt="Us" align="left" style="width:200px; margin-left:-40px;margin-right:30px") |   img(src="/resources/images/devguide/lifecycle-hooks/hooks-in-sequence.png" alt="Us" align="left" style="width:200px; margin-left:-40px;margin-right:30px") | ||||||
| 
 | 
 | ||||||
| :marked | :marked | ||||||
|   A component has a lifecycle managed by Angular itself. |   A component has a lifecycle managed by Angular. | ||||||
|    |    | ||||||
|   Angular creates it, renders it, creates and renders its children, |   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. |   checks it when its data-bound properties change, and destroys it before removing it from the DOM. | ||||||
| @ -19,32 +19,39 @@ figure | |||||||
|   <br class="l-clear-both"> |   <br class="l-clear-both"> | ||||||
| +ifDocsFor('ts|js') | +ifDocsFor('ts|js') | ||||||
|   :marked |   :marked | ||||||
|     ## Table of Contents |     ## Contents | ||||||
|     * [Overview](#hooks-overview) |     * [Component lifecycle hooks overview](#hooks-overview) | ||||||
|     * [Each hook's purpose and timing](#hooks-purpose-timing) |     * [Lifecycle sequence](#hooks-purpose-timing) | ||||||
|     * [Interfaces are optional (technically)](#interface-optional) |     * [Interfaces are optional (technically)](#interface-optional) | ||||||
|     * [Other Angular lifecycle hooks](#other-lifecycle-hooks) |     * [Other Angular lifecycle hooks](#other-lifecycle-hooks) | ||||||
|     * [The lifecycle sample](#the-sample) |     * [Lifecycle examples](#the-sample) | ||||||
|       * [All](#peek-a-boo) |     * [Peek-a-boo: all hooks](#peek-a-boo) | ||||||
|     * [Spying OnInit and OnDestroy](#spy) |     * [Spying OnInit and OnDestroy](#spy) | ||||||
|  |       * [OnInit](#oninit) | ||||||
|  |       * [OnDestroy](#ondestroy) | ||||||
|     * [OnChanges](#onchanges) |     * [OnChanges](#onchanges) | ||||||
|     * [DoCheck](#docheck) |     * [DoCheck](#docheck) | ||||||
|       * [AfterViewInit and AfterViewChecked](#afterview) |     * [AfterView](#afterview) | ||||||
|       * [AfterContentInit and AfterContentChecked](#aftercontent) |       * [Abide by the unidirectional data flow rule](#wait-a-tick) | ||||||
|  |     * [AfterContent](#aftercontent) | ||||||
|  |       * [Content projection](#content-projection) | ||||||
|  |       * [AfterContent hooks](#aftercontent-hooks) | ||||||
|  |       * [No unidirectional flow worries with _AfterContent_](#no-unidirectional-flow-worries) | ||||||
|  |    | ||||||
| :marked | :marked | ||||||
|   Try the <live-example></live-example>. |   Try the <live-example></live-example>. | ||||||
| 
 | 
 | ||||||
| a#hooks-overview | a#hooks-overview | ||||||
| .l-main-section | .l-main-section | ||||||
| :marked | :marked | ||||||
|   ## Component lifecycle hooks |   ## Component lifecycle hooks overview | ||||||
|   Directive and component instances have a lifecycle |   Directive and component instances have a lifecycle | ||||||
|   as Angular creates, updates, and destroys them. |   as Angular creates, updates, and destroys them. | ||||||
|   Developers can tap into key moments in that lifecycle by implementing |   Developers can tap into key moments in that lifecycle by implementing | ||||||
|   one or more of the *Lifecycle Hook* interfaces in the Angular `core` library. |   one or more of the *lifecycle hook* interfaces in the Angular `core` library. | ||||||
| 
 | 
 | ||||||
|   Each interface has a single hook method whose name is the interface name prefixed with `ng`. |   Each interface has a single hook method whose name is the interface name prefixed with `ng`. | ||||||
|   For example, the `OnInit` interface has a hook method named `ngOnInit`  |   For example, the `OnInit` interface has a hook method named `ngOnInit()`  | ||||||
|   that Angular calls shortly after creating the component: |   that Angular calls shortly after creating the component: | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/peek-a-boo.component.ts', 'ngOnInit', 'peek-a-boo.component.ts (excerpt)')(format='.') | +makeExample('lifecycle-hooks/ts/src/app/peek-a-boo.component.ts', 'ngOnInit', 'peek-a-boo.component.ts (excerpt)')(format='.') | ||||||
| :marked | :marked | ||||||
| @ -65,77 +72,77 @@ table(width="100%") | |||||||
|     th Purpose and Timing |     th Purpose and Timing | ||||||
| 
 | 
 | ||||||
|   tr(style=top) |   tr(style=top) | ||||||
|     td ngOnChanges |     td <code>ngOnChanges()</code> | ||||||
|     td |     td | ||||||
|       :marked |       :marked | ||||||
|         Respond when Angular (re)sets data-bound input properties. |         Respond when Angular (re)sets data-bound input properties. | ||||||
|         The method receives a `SimpleChanges` object of current and previous property values. |         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. |         Called before `ngOnInit()` and whenever one or more data-bound input properties change. | ||||||
| 
 | 
 | ||||||
|   tr(style=top) |   tr(style=top) | ||||||
|     td ngOnInit |     td <code>ngOnInit()</code> | ||||||
|     td |     td | ||||||
|       :marked |       :marked | ||||||
|         Initialize the directive/component after Angular first displays the data-bound properties |         Initialize the directive/component after Angular first displays the data-bound properties | ||||||
|         and sets the directive/component's input properties. |         and sets the directive/component's input properties. | ||||||
|          |          | ||||||
|         Called _once_, after the _first_ `ngOnChanges`.  |         Called _once_, after the _first_ `ngOnChanges()`.  | ||||||
| 
 | 
 | ||||||
|   tr(style=top) |   tr(style=top) | ||||||
|     td ngDoCheck |     td <code>ngDoCheck()</code> | ||||||
|     td |     td | ||||||
|       :marked |       :marked | ||||||
|         Detect and act upon changes that Angular can't or won't detect on its own.  |         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`. |         Called during every change detection run, immediately after `ngOnChanges()` and `ngOnInit()`. | ||||||
| 
 | 
 | ||||||
|   tr(style=top) |   tr(style=top) | ||||||
|     td ngAfterContentInit |     td <code>ngAfterContentInit()</code> | ||||||
|     td |     td | ||||||
|       :marked |       :marked | ||||||
|         Respond after Angular projects external content into the component's view. |         Respond after Angular projects external content into the component's view. | ||||||
| 
 | 
 | ||||||
|         Called _once_ after the first `NgDoCheck`. |         Called _once_ after the first `ngDoCheck()`. | ||||||
| 
 | 
 | ||||||
|         _A component-only hook_. |         _A component-only hook_. | ||||||
| 
 | 
 | ||||||
|   tr(style=top) |   tr(style=top) | ||||||
|     td ngAfterContentChecked |     td <code>ngAfterContentChecked()</code> | ||||||
|     td |     td | ||||||
|       :marked |       :marked | ||||||
|         Respond after Angular checks the content projected into the component. |         Respond after Angular checks the content projected into the component. | ||||||
| 
 | 
 | ||||||
|         Called after the `ngAfterContentInit` and every subsequent `NgDoCheck`. |         Called after the `ngAfterContentInit()` and every subsequent `ngDoCheck()`. | ||||||
| 
 | 
 | ||||||
|         _A component-only hook_. |         _A component-only hook_. | ||||||
| 
 | 
 | ||||||
|   tr(style=top) |   tr(style=top) | ||||||
|     td ngAfterViewInit |     td <code>ngAfterViewInit()</code> | ||||||
|     td |     td | ||||||
|       :marked |       :marked | ||||||
|         Respond after Angular initializes the component's views and child views. |         Respond after Angular initializes the component's views and child views. | ||||||
| 
 | 
 | ||||||
|         Called _once_ after the first `ngAfterContentChecked`. |         Called _once_ after the first `ngAfterContentChecked()`. | ||||||
| 
 | 
 | ||||||
|         _A component-only hook_. |         _A component-only hook_. | ||||||
| 
 | 
 | ||||||
|   tr(style=top) |   tr(style=top) | ||||||
|     td ngAfterViewChecked |     td <code>ngAfterViewChecked()</code> | ||||||
|     td |     td | ||||||
|       :marked |       :marked | ||||||
|         Respond after Angular checks the component's views and child views. |         Respond after Angular checks the component's views and child views. | ||||||
| 
 | 
 | ||||||
|         Called after the `ngAfterViewInit` and every subsequent `ngAfterContentChecked`. |         Called after the `ngAfterViewInit` and every subsequent `ngAfterContentChecked()`. | ||||||
| 
 | 
 | ||||||
|         _A component-only hook_. |         _A component-only hook_. | ||||||
| 
 | 
 | ||||||
|   tr(style=top) |   tr(style=top) | ||||||
|     td ngOnDestroy |     td <code>ngOnDestroy</code> | ||||||
|     td |     td | ||||||
|       :marked |       :marked | ||||||
|         Cleanup just before Angular destroys the directive/component. |         Cleanup just before Angular destroys the directive/component. | ||||||
|         Unsubscribe observables and detach event handlers to avoid memory leaks.       |         Unsubscribe Observables and detach event handlers to avoid memory leaks.       | ||||||
| 
 | 
 | ||||||
|         Called _just before_ Angular destroys the directive/component. |         Called _just before_ Angular destroys the directive/component. | ||||||
| 
 | 
 | ||||||
| @ -143,7 +150,7 @@ table(width="100%") | |||||||
|   a#interface-optional |   a#interface-optional | ||||||
|   .l-main-section   |   .l-main-section   | ||||||
|   :marked |   :marked | ||||||
|     ## Interface are optional (technically) |     ## Interfaces are optional (technically) | ||||||
| 
 | 
 | ||||||
|     The interfaces are optional for JavaScript and Typescript developers from a purely technical perspective. |     The interfaces are optional for JavaScript and Typescript developers from a purely technical perspective. | ||||||
|     The JavaScript language doesn't have interfaces. |     The JavaScript language doesn't have interfaces. | ||||||
| @ -161,7 +168,7 @@ table(width="100%") | |||||||
| a#other-lifecycle-hooks | a#other-lifecycle-hooks | ||||||
| .l-main-section | .l-main-section | ||||||
| :marked | :marked | ||||||
|   ## Other lifecycle hooks |   ## Other Angular lifecycle hooks | ||||||
| 
 | 
 | ||||||
|   Other Angular sub-systems may have their own lifecycle hooks apart from these component hooks. |   Other Angular sub-systems may have their own lifecycle hooks apart from these component hooks. | ||||||
| 
 | 
 | ||||||
| @ -174,7 +181,7 @@ block other-angular-subsystems | |||||||
| 
 | 
 | ||||||
| .l-main-section#the-sample | .l-main-section#the-sample | ||||||
| :marked | :marked | ||||||
|   ## Lifecycle exercises |   ## Lifecycle examples | ||||||
| 
 | 
 | ||||||
|   The <live-example></live-example> |   The <live-example></live-example> | ||||||
|   demonstrates the lifecycle hooks in action through a series of exercises |   demonstrates the lifecycle hooks in action through a series of exercises | ||||||
| @ -211,14 +218,14 @@ table(width="100%") | |||||||
|     td <a href="#onchanges">OnChanges</a> |     td <a href="#onchanges">OnChanges</a> | ||||||
|     td |     td | ||||||
|       :marked |       :marked | ||||||
|         See how Angular calls the `ngOnChanges` hook with a `changes` object |         See how Angular calls the `ngOnChanges()` hook with a `changes` object | ||||||
|         every time one of the component input properties changes. |         every time one of the component input properties changes. | ||||||
|         Shows how to interpret the `changes` object. |         Shows how to interpret the `changes` object. | ||||||
|   tr(style=top) |   tr(style=top) | ||||||
|     td <a href="#docheck">DoCheck</a> |     td <a href="#docheck">DoCheck</a> | ||||||
|     td |     td | ||||||
|       :marked |       :marked | ||||||
|         Implements an `ngDoCheck` method with custom change detection. |         Implements an `ngDoCheck()` method with custom change detection. | ||||||
|         See how often Angular calls this hook and watch it post changes to a log. |         See how often Angular calls this hook and watch it post changes to a log. | ||||||
|   tr(style=top) |   tr(style=top) | ||||||
|     td <a href="#afterview">AfterView</a> |     td <a href="#afterview">AfterView</a> | ||||||
| @ -246,7 +253,7 @@ table(width="100%") | |||||||
|         to the `CounterComponent` log where it watches log entries being created and destroyed. |         to the `CounterComponent` log where it watches log entries being created and destroyed. | ||||||
| 
 | 
 | ||||||
| :marked | :marked | ||||||
|   The remainder of this chapter discusses selected exercises in further detail. |   The remainder of this page discusses selected exercises in further detail. | ||||||
| 
 | 
 | ||||||
| a#peek-a-boo | a#peek-a-boo | ||||||
| .l-main-section | .l-main-section | ||||||
| @ -272,7 +279,7 @@ figure.image-display | |||||||
| :marked | :marked | ||||||
|   Had the user clicked the *Update Hero* button, the log would show another `OnChanges` and two more triplets of |   Had the user clicked the *Update Hero* button, the log would show another `OnChanges` and two more triplets of | ||||||
|   `DoCheck`, `AfterContentChecked` and `AfterViewChecked`. |   `DoCheck`, `AfterContentChecked` and `AfterViewChecked`. | ||||||
|   Clearly these three hooks fire a *often*. Keep the logic in these hooks as lean as possible! |   Clearly these three hooks fire *often*. Keep the logic in these hooks as lean as possible! | ||||||
| 
 | 
 | ||||||
|   The next examples focus on hook details. |   The next examples focus on hook details. | ||||||
| 
 | 
 | ||||||
| @ -293,13 +300,13 @@ a#spy | |||||||
|     1. Angular calls hook methods for *directives* as well as components.<br><br> |     1. Angular calls hook methods for *directives* as well as components.<br><br> | ||||||
| 
 | 
 | ||||||
|     2. A spy directive can provide insight into a DOM object that you cannot change directly. |     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`. |     Obviously you can't touch the implementation of a native `<div>`. | ||||||
|     You can't modify a third party component either. |     You can't modify a third party component either. | ||||||
|     But you can watch both with a directive. |     But you can watch both with a directive. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| :marked | :marked | ||||||
|   The sneaky spy directive is simple,  consisting almost entirely of `ngOnInit` and `ngOnDestroy` hooks |   The sneaky spy directive is simple, consisting almost entirely of `ngOnInit()` and `ngOnDestroy()` hooks | ||||||
|   that log messages to the parent via an injected `LoggerService`. |   that log messages to the parent via an injected `LoggerService`. | ||||||
| 
 | 
 | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/spy.directive.ts', 'spy-directive')(format=".") | +makeExample('lifecycle-hooks/ts/src/app/spy.directive.ts', 'spy-directive')(format=".") | ||||||
| @ -307,7 +314,7 @@ a#spy | |||||||
| :marked | :marked | ||||||
|   You can apply the spy to any native or component element and it'll be initialized and destroyed |   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. |   at the same time as that element. | ||||||
|   Here it is attached to the repeated hero `<div>` |   Here it is attached to the repeated hero `<div>`: | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/spy.component.html', 'template')(format=".") | +makeExample('lifecycle-hooks/ts/src/app/spy.component.html', 'template')(format=".") | ||||||
| 
 | 
 | ||||||
| :marked | :marked | ||||||
| @ -318,19 +325,20 @@ figure.image-display | |||||||
|   img(src='/resources/images/devguide/lifecycle-hooks/spy-directive.gif' alt="Spy Directive") |   img(src='/resources/images/devguide/lifecycle-hooks/spy-directive.gif' alt="Spy Directive") | ||||||
| 
 | 
 | ||||||
| :marked | :marked | ||||||
|   Adding a hero results in a new hero `<div>`. The spy's `ngOnInit` logs that event. |   Adding a hero results in a new hero `<div>`. The spy's `ngOnInit()` logs that event. | ||||||
| 
 | 
 | ||||||
|   The *Reset* button clears the `heroes` list. |   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. |   Angular removes all hero `<div>` elements from the DOM and destroys their spy directives at the same time. | ||||||
|   The spy's `ngOnDestroy` method reports its last moments. |   The spy's `ngOnDestroy()` method reports its last moments. | ||||||
| 
 | 
 | ||||||
|   The `ngOnInit` and `ngOnDestroy` methods have more vital roles to play in real applications. |   The `ngOnInit()` and `ngOnDestroy()` methods have more vital roles to play in real applications. | ||||||
|  | a#oninit | ||||||
|  | :marked | ||||||
|  |   ### _OnInit()_ | ||||||
| 
 | 
 | ||||||
|   ### OnInit |   Use `ngOnInit()` for two main reasons: | ||||||
| 
 |   1. To perform complex initializations shortly after construction. | ||||||
|   Use `ngOnInit` for two main reasons: |   1. To set up the component after Angular sets the input properties. | ||||||
|   1. to perform complex initializations shortly after construction |  | ||||||
|   1. to set up the component after Angular sets the input properties |  | ||||||
| 
 | 
 | ||||||
|   Experienced developers agree that components should be cheap and safe to construct. |   Experienced developers agree that components should be cheap and safe to construct. | ||||||
| .l-sub-section | .l-sub-section | ||||||
| @ -345,43 +353,46 @@ figure.image-display | |||||||
|   created under test or before you decide to display it. |   created under test or before you decide to display it. | ||||||
|   Constructors should do no more than set the initial local variables to simple values. |   Constructors should do no more than set the initial local variables to simple values. | ||||||
|    |    | ||||||
|   An `ngOnInit` is a good place for a component to fetch its initial data. The |   An `ngOnInit()` is a good place for a component to fetch its initial data. The | ||||||
|   [Tutorial](../tutorial/toh-pt4.html#oninit) and [HTTP](server-communication.html#oninit) chapter |   [Tour of Heroes Tutorial](../tutorial/toh-pt4.html#oninit) and [HTTP Client](server-communication.html#oninit)  | ||||||
|   show how. |   guides show how. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|   Remember also that a directive's data-bound input properties are not set until _after construction_. |   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. |   That's a problem if you need to initialize the directive based on those properties. | ||||||
|   They'll have been set when `ngOninit` runs. |   They'll have been set when `ngOnInit()` runs. | ||||||
| .l-sub-section | .l-sub-section | ||||||
|   :marked |   :marked | ||||||
|     The `ngOnChanges` method is your first opportunity to access those properties. |     The `ngOnChanges()` method is your first opportunity to access those properties. | ||||||
|     Angular calls `ngOnChanges` before `ngOnInit` ... and many times after that. |     Angular calls `ngOnChanges()` before `ngOnInit()` and many times after that. | ||||||
|     It only calls `ngOnInit` once. |     It only calls `ngOnInit()` once. | ||||||
| :marked | :marked | ||||||
|   You can count on Angular to call the `ngOnInit` method _soon_ after creating the component. |   You can count on Angular to call the `ngOnInit()` method _soon_ after creating the component. | ||||||
|   That's where the heavy initialization logic belongs. |   That's where the heavy initialization logic belongs. | ||||||
| 
 | 
 | ||||||
|   ### OnDestroy | a#ondestroy | ||||||
|  | :marked | ||||||
|  |   ### _OnDestroy()_ | ||||||
| 
 | 
 | ||||||
|   Put cleanup logic in `ngOnDestroy`, the logic that *must* run before Angular destroys the directive. |   Put cleanup logic in `ngOnDestroy()`, the logic that *must* run before Angular destroys the directive. | ||||||
| 
 | 
 | ||||||
|   This is the time to notify another part of the application that the component is going away. |   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. |   This is the place to free resources that won't be garbage collected automatically. | ||||||
|   Unsubscribe from observables and DOM events. Stop interval timers. |   Unsubscribe from Observables and DOM events. Stop interval timers. | ||||||
|   Unregister all callbacks that this directive registered with global or application services. |   Unregister all callbacks that this directive registered with global or application services. | ||||||
|   You risk memory leaks if you neglect to do so. |   You risk memory leaks if you neglect to do so. | ||||||
| 
 | 
 | ||||||
| .l-main-section | .l-main-section | ||||||
|  | a#onchanges | ||||||
| :marked | :marked | ||||||
|   ## OnChanges |   ## _OnChanges()_ | ||||||
| 
 | 
 | ||||||
|   Angular calls its `ngOnChanges` method whenever it detects changes to ***input properties*** of the component (or directive). |   Angular calls its `ngOnChanges()` method whenever it detects changes to ***input properties*** of the component (or directive). | ||||||
|   This example monitors the `OnChanges` hook. |   This example monitors the `OnChanges` hook. | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/on-changes.component.ts', 'ng-on-changes', 'OnChangesComponent (ngOnChanges)')(format=".") | +makeExample('lifecycle-hooks/ts/src/app/on-changes.component.ts', 'ng-on-changes', 'on-changes.component.ts (excerpt)')(format=".") | ||||||
| :marked | :marked | ||||||
|   The `ngOnChanges` method takes an object that maps each changed property name to a |   The `ngOnChanges()` method takes an object that maps each changed property name to a | ||||||
|   [SimpleChange](../api/core/index/SimpleChange-class.html) object holding the current and previous property values. |   [SimpleChange](../api/core/index/SimpleChange-class.html) object holding the current and previous property values. | ||||||
|   This hook iterates over the changed properties and logs them. |   This hook iterates over the changed properties and logs them. | ||||||
| 
 | 
 | ||||||
| @ -408,58 +419,60 @@ figure.image-display | |||||||
|   The hero object *reference* didn't change so, from Angular's perspective, there is no change to report! |   The hero object *reference* didn't change so, from Angular's perspective, there is no change to report! | ||||||
| 
 | 
 | ||||||
| .l-main-section | .l-main-section | ||||||
|  | a#docheck | ||||||
| :marked | :marked | ||||||
|   ## DoCheck |   ## _DoCheck()_ | ||||||
|   Use the `DoCheck` hook to detect and act upon changes that Angular doesn't catch on its own. |   Use the `DoCheck` hook to detect and act upon changes that Angular doesn't catch on its own. | ||||||
| .l-sub-section | .l-sub-section | ||||||
|   :marked |   :marked | ||||||
|     Use this method to detect a change that Angular overlooked. |     Use this method to detect a change that Angular overlooked. | ||||||
| :marked | :marked | ||||||
|   The *DoCheck* sample extends the *OnChanges* sample with the following `ngDoCheck` hook: |   The *DoCheck* sample extends the *OnChanges* sample with the following `ngDoCheck()` hook: | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/do-check.component.ts', 'ng-do-check', 'DoCheckComponent (ngDoCheck)')(format=".") | +makeExample('lifecycle-hooks/ts/src/app/do-check.component.ts', 'ng-do-check', 'DoCheckComponent (ngDoCheck)')(format=".") | ||||||
| :marked | :marked | ||||||
|   This code inspects certain _values-of-interest_, capturing and comparing their current state against previous values. |   This code inspects certain _values of interest_, capturing and comparing their current state against previous values. | ||||||
|   It writes a special message to the log when there are no substantive changes to the `hero` or the `power` |   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: |   so you can see how often `DoCheck` is called. The results are illuminating: | ||||||
| 
 | 
 | ||||||
| figure.image-display | figure.image-display | ||||||
|   img(src='/resources/images/devguide/lifecycle-hooks/do-check-anim.gif' alt="DoCheck") |   img(src='/resources/images/devguide/lifecycle-hooks/do-check-anim.gif' alt="DoCheck") | ||||||
| :marked | :marked | ||||||
|   While the `ngDoCheck` hook can detect when the hero's `name` has changed, it has a frightful cost. |   While the `ngDoCheck()` hook can detect when the hero's `name` has changed, it has a frightful cost. | ||||||
|   This hook is called with enormous frequency — |   This hook is called with enormous frequency—after _every_  | ||||||
|   after _every_ change detection cycle no matter where the change occurred. |   change detection cycle no matter where the change occurred. | ||||||
|   It's called over twenty times in this example before the user can do anything. |   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*. |   Most of these initial checks are triggered by Angular's first rendering of *unrelated data elsewhere on the page*. | ||||||
|   Mere mousing into another input box triggers a call. |   Mere mousing into another `<input>` triggers a call. | ||||||
|   Relatively few calls reveal actual changes to pertinent data. |   Relatively few calls reveal actual changes to pertinent data. | ||||||
|   Clearly our implementation must be very lightweight or the user experience will suffer. |   Clearly our implementation must be very lightweight or the user experience suffers. | ||||||
| 
 | 
 | ||||||
| .l-main-section | .l-main-section | ||||||
|  | a#afterview | ||||||
| :marked | :marked | ||||||
|   ## AfterView |   ## AfterView | ||||||
|   The *AfterView* sample explores the `AfterViewInit` and `AfterViewChecked` hooks that Angular calls |   The *AfterView* sample explores the `AfterViewInit()` and `AfterViewChecked()` hooks that Angular calls | ||||||
|   *after* it creates a component's child views. |   *after* it creates a component's child views. | ||||||
| 
 | 
 | ||||||
|   Here's a child view that displays a hero's name in an input box: |   Here's a child view that displays a hero's name in an `<input>`: | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/after-view.component.ts', 'child-view', 'ChildComponent')(format=".") | +makeExample('lifecycle-hooks/ts/src/app/after-view.component.ts', 'child-view', 'ChildComponent')(format=".") | ||||||
| :marked | :marked | ||||||
|   The `AfterViewComponent` displays this child view *within its template*: |   The `AfterViewComponent` displays this child view *within its template*: | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/after-view.component.ts', 'template', 'AfterViewComponent (template)')(format=".") | +makeExample('lifecycle-hooks/ts/src/app/after-view.component.ts', 'template', 'AfterViewComponent (template)')(format=".") | ||||||
| :marked | :marked | ||||||
|   The following hooks take action based on changing values *within the child view* |   The following hooks take action based on changing values *within the child view*, | ||||||
|   which can only be reached by querying for the child view via the property decorated with |   which can only be reached by querying for the child view via the property decorated with | ||||||
|   [@ViewChild](../api/core/index/ViewChild-decorator.html). |   [@ViewChild](../api/core/index/ViewChild-decorator.html). | ||||||
| 
 | 
 | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/after-view.component.ts', 'hooks', 'AfterViewComponent (class excerpts)')(format=".") | +makeExample('lifecycle-hooks/ts/src/app/after-view.component.ts', 'hooks', 'AfterViewComponent (class excerpts)')(format=".") | ||||||
| #wait-a-tick | a#wait-a-tick | ||||||
| :marked | :marked | ||||||
|   ### Abide by the unidirectional data flow rule |   ### Abide by the unidirectional data flow rule | ||||||
|   The `doSomething` method updates the screen when the hero name exceeds 10 characters. |   The `doSomething()` method updates the screen when the hero name exceeds 10 characters. | ||||||
| 
 | 
 | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/after-view.component.ts', 'do-something', 'AfterViewComponent (doSomething)')(format=".") | +makeExample('lifecycle-hooks/ts/src/app/after-view.component.ts', 'do-something', 'AfterViewComponent (doSomething)')(format=".") | ||||||
| :marked | :marked | ||||||
|   Why does the `doSomething` method wait a tick before updating `comment`? |   Why does the `doSomething()` method wait a tick before updating `comment`? | ||||||
| 
 | 
 | ||||||
|   Angular's unidirectional data flow rule forbids updates to the view *after* it has been composed. |   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. |   Both of these hooks fire _after_ the component's view has been composed. | ||||||
| @ -468,22 +481,25 @@ figure.image-display | |||||||
| block tick-methods | block tick-methods | ||||||
|   :marked |   :marked | ||||||
|     The `LoggerService.tick_then()` postpones the log update  |     The `LoggerService.tick_then()` postpones the log update  | ||||||
|     for one turn of the browser's JavaScript cycle ... and that's just long enough. |     for one turn of the browser's JavaScript cycle and that's just long enough. | ||||||
| 
 | 
 | ||||||
| :marked | :marked | ||||||
|   Here's *AfterView* in action |   Here's *AfterView* in action: | ||||||
| figure.image-display | figure.image-display | ||||||
|   img(src='/resources/images/devguide/lifecycle-hooks/after-view-anim.gif' alt="AfterView") |   img(src='/resources/images/devguide/lifecycle-hooks/after-view-anim.gif' alt="AfterView") | ||||||
| :marked | :marked | ||||||
|   Notice that Angular frequently calls `AfterViewChecked`, often when there are no changes of interest. |   Notice that Angular frequently calls `AfterViewChecked()`, often when there are no changes of interest. | ||||||
|   Write lean hook methods to avoid performance problems. |   Write lean hook methods to avoid performance problems. | ||||||
| 
 | 
 | ||||||
| .l-main-section | .l-main-section | ||||||
|  | a#aftercontent | ||||||
| :marked | :marked | ||||||
|   ## AfterContent |   ## AfterContent | ||||||
|   The *AfterContent* sample explores the `AfterContentInit` and `AfterContentChecked` hooks that Angular calls |   The *AfterContent* sample explores the `AfterContentInit()` and `AfterContentChecked()` hooks that Angular calls | ||||||
|   *after* Angular projects external content into the component. |   *after* Angular projects external content into the component. | ||||||
|    |    | ||||||
|  | a#content-projection | ||||||
|  | :marked | ||||||
|   ### Content projection |   ### Content projection | ||||||
|   *Content projection* is a way to import HTML content from outside the component and insert that content |   *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. |   into the component's template in a designated spot. | ||||||
| @ -495,7 +511,7 @@ figure.image-display | |||||||
| :marked | :marked | ||||||
|   Consider this variation on the [previous _AfterView_](#afterview) example. |   Consider this variation on the [previous _AfterView_](#afterview) example. | ||||||
|   This time, instead of including the child view within the template, it imports the content from |   This time, instead of including the child view within the template, it imports the content from | ||||||
|   the `AfterContentComponent`'s parent. Here's the parent's template. |   the `AfterContentComponent`'s parent. Here's the parent's template: | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/after-content.component.ts', 'parent-template', 'AfterContentParentComponent (template excerpt)')(format=".") | +makeExample('lifecycle-hooks/ts/src/app/after-content.component.ts', 'parent-template', 'AfterContentParentComponent (template excerpt)')(format=".") | ||||||
| :marked | :marked | ||||||
|   Notice that the `<my-child>` tag is tucked between the `<after-content>` tags. |   Notice that the `<my-child>` tag is tucked between the `<after-content>` tags. | ||||||
| @ -513,12 +529,14 @@ figure.image-display | |||||||
| :marked | :marked | ||||||
| .l-sub-section | .l-sub-section | ||||||
|   :marked |   :marked | ||||||
|     The tell-tale signs of *content projection* are (a) HTML between component element tags |     The telltale signs of *content projection* are twofold:  | ||||||
|     and (b) the presence of `<ng-content>` tags in the component's template. |       - HTML between component element tags. | ||||||
|  |       - The presence of `<ng-content>` tags in the component's template. | ||||||
|  | a#aftercontent-hooks | ||||||
| :marked | :marked | ||||||
|   ### AfterContent hooks |   ### AfterContent hooks | ||||||
|   *AfterContent* hooks are similar to the *AfterView* hooks.  |   *AfterContent* hooks are similar to the *AfterView* hooks.  | ||||||
|   The key difference is in the child component |   The key difference is in the child component. | ||||||
| 
 | 
 | ||||||
|   * The *AfterView* hooks concern `ViewChildren`, the child components whose element tags |   * The *AfterView* hooks concern `ViewChildren`, the child components whose element tags | ||||||
|   appear *within* the component's template. |   appear *within* the component's template. | ||||||
| @ -526,17 +544,17 @@ figure.image-display | |||||||
|   * The *AfterContent* hooks concern `ContentChildren`, the child components that Angular |   * The *AfterContent* hooks concern `ContentChildren`, the child components that Angular | ||||||
|   projected into the component. |   projected into the component. | ||||||
| 
 | 
 | ||||||
|   The following *AfterContent* hooks take action based on changing values in a  *content child* |   The following *AfterContent* hooks take action based on changing values in a *content child*, | ||||||
|   which can only be reached by querying for it via the property decorated with |   which can only be reached by querying for them via the property decorated with | ||||||
|   [@ContentChild](../api/core/index/ContentChild-decorator.html). |   [@ContentChild](../api/core/index/ContentChild-decorator.html). | ||||||
| 
 | 
 | ||||||
| +makeExample('lifecycle-hooks/ts/src/app/after-content.component.ts', 'hooks', 'AfterContentComponent (class excerpts)')(format=".") | +makeExample('lifecycle-hooks/ts/src/app/after-content.component.ts', 'hooks', 'AfterContentComponent (class excerpts)')(format=".") | ||||||
| 
 | 
 | ||||||
| a#no-unidirectional-flow-worries | a#no-unidirectional-flow-worries | ||||||
| :marked | :marked | ||||||
|    ### No unidirectional flow worries with _AfterContent..._ |    ### No unidirectional flow worries with _AfterContent_ | ||||||
| 
 | 
 | ||||||
|    This component's `doSomething` method update's the component's data-bound `comment` property immediately. |    This component's `doSomething()` method update's the component's data-bound `comment` property immediately. | ||||||
|    There's no [need to wait](#wait-a-tick). |    There's no [need to wait](#wait-a-tick). | ||||||
| 
 | 
 | ||||||
|    Recall that Angular calls both *AfterContent* hooks before calling either of the *AfterView* hooks. |    Recall that Angular calls both *AfterContent* hooks before calling either of the *AfterView* hooks. | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user