diff --git a/aio/content/examples/lifecycle-hooks/src/app/after-content-parent.component.ts b/aio/content/examples/lifecycle-hooks/src/app/after-content-parent.component.ts new file mode 100644 index 0000000000..18c055c824 --- /dev/null +++ b/aio/content/examples/lifecycle-hooks/src/app/after-content-parent.component.ts @@ -0,0 +1,38 @@ +import { Component } from '@angular/core'; + +import { LoggerService } from './logger.service'; + +@Component({ + selector: 'after-content-parent', + template: ` +
+

AfterContent

+ +
` + + // #docregion parent-template + ` + + ` + // #enddocregion parent-template + + `
+ +

-- AfterContent Logs --

+

+
{{msg}}
+
+ `, + styles: ['.parent {background: burlywood}'], + providers: [LoggerService] +}) +export class AfterContentParentComponent { + show = true; + + constructor(public logger: LoggerService) { } + + reset() { + this.logger.clear(); + // quickly remove and reload AfterContentComponent which recreates it + this.show = false; + this.logger.tick_then(() => this.show = true); + } +} diff --git a/aio/content/examples/lifecycle-hooks/src/app/after-content.component.ts b/aio/content/examples/lifecycle-hooks/src/app/after-content.component.ts index 1de8a84612..69b4342879 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/after-content.component.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/after-content.component.ts @@ -2,18 +2,9 @@ // #docregion import { AfterContentChecked, AfterContentInit, Component, ContentChild } from '@angular/core'; +import { ChildComponent } from './child.component'; import { LoggerService } from './logger.service'; -////////////////// -@Component({ - selector: 'app-child', - template: '' -}) -export class ChildComponent { - hero = 'Magneta'; -} - -////////////////////// @Component({ selector: 'after-content', // #docregion template @@ -75,40 +66,3 @@ export class AfterContentComponent implements AfterContentChecked, AfterContentI // ... } // #enddocregion hooks - -////////////// -@Component({ - selector: 'after-content-parent', - template: ` -
-

AfterContent

- -
` + -// #docregion parent-template - ` - - ` -// #enddocregion parent-template -+ `
- -

-- AfterContent Logs --

-

-
{{msg}}
-
- `, - styles: ['.parent {background: burlywood}'], - providers: [LoggerService] -}) -export class AfterContentParentComponent { - show = true; - - constructor(public logger: LoggerService) { - } - - reset() { - this.logger.clear(); - // quickly remove and reload AfterContentComponent which recreates it - this.show = false; - this.logger.tick_then(() => this.show = true); - } -} diff --git a/aio/content/examples/lifecycle-hooks/src/app/after-view-parent.component.ts b/aio/content/examples/lifecycle-hooks/src/app/after-view-parent.component.ts new file mode 100644 index 0000000000..20158287e3 --- /dev/null +++ b/aio/content/examples/lifecycle-hooks/src/app/after-view-parent.component.ts @@ -0,0 +1,32 @@ +import { Component } from '@angular/core'; + +import { LoggerService } from './logger.service'; + +@Component({ + selector: 'after-view-parent', + template: ` +
+

AfterView

+ + + +

-- AfterView Logs --

+

+
{{msg}}
+
+ `, + styles: ['.parent {background: burlywood}'], + providers: [LoggerService] +}) +export class AfterViewParentComponent { + show = true; + + constructor(public logger: LoggerService) { } + + reset() { + this.logger.clear(); + // quickly remove and reload AfterViewComponent which recreates it + this.show = false; + this.logger.tick_then(() => this.show = true); + } +} diff --git a/aio/content/examples/lifecycle-hooks/src/app/after-view.component.ts b/aio/content/examples/lifecycle-hooks/src/app/after-view.component.ts index 534d0b4090..7c25a513b5 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/after-view.component.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/after-view.component.ts @@ -2,20 +2,9 @@ // #docregion import { AfterViewChecked, AfterViewInit, Component, ViewChild } from '@angular/core'; +import { ChildViewComponent } from './child-view.component'; import { LoggerService } from './logger.service'; -////////////////// -// #docregion child-view -@Component({ - selector: 'app-child-view', - template: '' -}) -export class ChildViewComponent { - hero = 'Magneta'; -} -// #enddocregion child-view - -////////////////////// @Component({ selector: 'after-view', // #docregion template @@ -84,34 +73,3 @@ export class AfterViewComponent implements AfterViewChecked, AfterViewInit { // ... } // #enddocregion hooks - -////////////// -@Component({ - selector: 'after-view-parent', - template: ` -
-

AfterView

- - - -

-- AfterView Logs --

-

-
{{msg}}
-
- `, - styles: ['.parent {background: burlywood}'], - providers: [LoggerService] -}) -export class AfterViewParentComponent { - show = true; - - constructor(public logger: LoggerService) { - } - - reset() { - this.logger.clear(); - // quickly remove and reload AfterViewComponent which recreates it - this.show = false; - this.logger.tick_then(() => this.show = true); - } -} diff --git a/aio/content/examples/lifecycle-hooks/src/app/app.module.ts b/aio/content/examples/lifecycle-hooks/src/app/app.module.ts index 4d9cabf218..383f6c2a3f 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/app.module.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/app.module.ts @@ -5,32 +5,22 @@ import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; -import { - AfterContentParentComponent, - AfterContentComponent, - ChildComponent -} from './after-content.component'; +import { AfterContentParentComponent } from './after-content-parent.component'; +import { AfterContentComponent } from './after-content.component'; +import { ChildComponent } from './child.component'; -import { - AfterViewParentComponent, - AfterViewComponent, - ChildViewComponent -} from './after-view.component'; +import { AfterViewParentComponent } from './after-view-parent.component'; +import { AfterViewComponent } from './after-view.component'; +import { ChildViewComponent } from './child-view.component'; -import { - CounterParentComponent, - MyCounterComponent -} from './counter.component'; +import { CounterParentComponent } from './counter-parent.component'; +import { MyCounterComponent } from './counter.component'; -import { - DoCheckParentComponent, - DoCheckComponent -} from './do-check.component'; +import { DoCheckParentComponent } from './do-check-parent.component'; +import { DoCheckComponent } from './do-check.component'; -import { - OnChangesParentComponent, - OnChangesComponent -} from './on-changes.component'; +import { OnChangesParentComponent } from './on-changes-parent.component'; +import { OnChangesComponent } from './on-changes.component'; import { PeekABooParentComponent } from './peek-a-boo-parent.component'; import { PeekABooComponent } from './peek-a-boo.component'; diff --git a/aio/content/examples/lifecycle-hooks/src/app/child-view.component.ts b/aio/content/examples/lifecycle-hooks/src/app/child-view.component.ts new file mode 100644 index 0000000000..80664a9a09 --- /dev/null +++ b/aio/content/examples/lifecycle-hooks/src/app/child-view.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +// #docregion child-view +@Component({ + selector: 'app-child-view', + template: '' +}) +export class ChildViewComponent { + hero = 'Magneta'; +} +// #enddocregion child-view diff --git a/aio/content/examples/lifecycle-hooks/src/app/child.component.ts b/aio/content/examples/lifecycle-hooks/src/app/child.component.ts new file mode 100644 index 0000000000..d990c1c476 --- /dev/null +++ b/aio/content/examples/lifecycle-hooks/src/app/child.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-child', + template: '' +}) +export class ChildComponent { + hero = 'Magneta'; +} diff --git a/aio/content/examples/lifecycle-hooks/src/app/counter-parent.component.ts b/aio/content/examples/lifecycle-hooks/src/app/counter-parent.component.ts new file mode 100644 index 0000000000..651ac5a34f --- /dev/null +++ b/aio/content/examples/lifecycle-hooks/src/app/counter-parent.component.ts @@ -0,0 +1,45 @@ +import { Component } from '@angular/core'; + +import { LoggerService } from './logger.service'; + +@Component({ + selector: 'counter-parent', + template: ` +
+

Counter Spy

+ + + + + + +

-- Spy Lifecycle Hook Log --

+
{{msg}}
+
+ `, + styles: ['.parent {background: gold;}'], + providers: [LoggerService] +}) +export class CounterParentComponent { + value: number; + spyLog: string[] = []; + + private logger: LoggerService; + + constructor(logger: LoggerService) { + this.logger = logger; + this.spyLog = logger.logs; + this.reset(); + } + + updateCounter() { + this.value += 1; + this.logger.tick(); + } + + reset() { + this.logger.log('-- reset --'); + this.value = 0; + this.logger.tick(); + } +} diff --git a/aio/content/examples/lifecycle-hooks/src/app/counter.component.ts b/aio/content/examples/lifecycle-hooks/src/app/counter.component.ts index a2d7b5fd9b..192cc06f7e 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/counter.component.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/counter.component.ts @@ -4,8 +4,6 @@ import { OnChanges, SimpleChanges, } from '@angular/core'; -import { LoggerService } from './logger.service'; - @Component({ selector: 'app-counter', template: ` @@ -37,46 +35,3 @@ export class MyCounterComponent implements OnChanges { this.changeLog.push(`counter: currentValue = ${cur}, previousValue = ${prev}`); } } - -@Component({ - selector: 'counter-parent', - template: ` -
-

Counter Spy

- - - - - - -

-- Spy Lifecycle Hook Log --

-
{{msg}}
-
- `, - styles: ['.parent {background: gold;}'], - providers: [LoggerService] -}) -export class CounterParentComponent { - value: number; - spyLog: string[] = []; - - private logger: LoggerService; - - constructor(logger: LoggerService) { - this.logger = logger; - this.spyLog = logger.logs; - this.reset(); - } - - updateCounter() { - this.value += 1; - this.logger.tick(); - } - - reset() { - this.logger.log('-- reset --'); - this.value = 0; - this.logger.tick(); - } -} - diff --git a/aio/content/examples/lifecycle-hooks/src/app/do-check-parent.component.ts b/aio/content/examples/lifecycle-hooks/src/app/do-check-parent.component.ts new file mode 100644 index 0000000000..9ac6a3b88a --- /dev/null +++ b/aio/content/examples/lifecycle-hooks/src/app/do-check-parent.component.ts @@ -0,0 +1,28 @@ +import { Component, ViewChild } from '@angular/core'; + +import { DoCheckComponent } from './do-check.component'; +import { Hero } from './hero'; + +@Component({ + selector: 'do-check-parent', + templateUrl: './do-check-parent.component.html', + styles: ['.parent {background: Lavender}'] +}) +export class DoCheckParentComponent { + hero: Hero; + power: string; + title = 'DoCheck'; + @ViewChild(DoCheckComponent) childView: DoCheckComponent; + + constructor() { + this.reset(); + } + + reset() { + this.hero = new Hero('Windstorm'); + this.power = 'sing'; + if (this.childView) { + this.childView.reset(); + } + } +} diff --git a/aio/content/examples/lifecycle-hooks/src/app/do-check.component.ts b/aio/content/examples/lifecycle-hooks/src/app/do-check.component.ts index 82a830dd98..33b006d907 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/do-check.component.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/do-check.component.ts @@ -1,10 +1,8 @@ /* tslint:disable:forin */ // #docregion -import { Component, DoCheck, Input, ViewChild } from '@angular/core'; +import { Component, DoCheck, Input } from '@angular/core'; -class Hero { - constructor(public name: string) {} -} +import { Hero } from './hero'; @Component({ selector: 'do-check', @@ -71,23 +69,3 @@ export class DoCheckComponent implements DoCheck { this.changeLog = []; } } - -@Component({ - selector: 'do-check-parent', - templateUrl: './do-check-parent.component.html', - styles: ['.parent {background: Lavender}'] -}) -export class DoCheckParentComponent { - hero: Hero; - power: string; - title = 'DoCheck'; - @ViewChild(DoCheckComponent) childView: DoCheckComponent; - - constructor() { this.reset(); } - - reset() { - this.hero = new Hero('Windstorm'); - this.power = 'sing'; - if (this.childView) { this.childView.reset(); } - } -} diff --git a/aio/content/examples/lifecycle-hooks/src/app/hero.ts b/aio/content/examples/lifecycle-hooks/src/app/hero.ts new file mode 100644 index 0000000000..d30f82ba39 --- /dev/null +++ b/aio/content/examples/lifecycle-hooks/src/app/hero.ts @@ -0,0 +1,3 @@ +export class Hero { + constructor(public name: string) { } +} diff --git a/aio/content/examples/lifecycle-hooks/src/app/on-changes-parent.component.ts b/aio/content/examples/lifecycle-hooks/src/app/on-changes-parent.component.ts new file mode 100644 index 0000000000..fa47c6d935 --- /dev/null +++ b/aio/content/examples/lifecycle-hooks/src/app/on-changes-parent.component.ts @@ -0,0 +1,30 @@ +import { Component, ViewChild } from '@angular/core'; + +import { Hero } from './hero'; +import { OnChangesComponent } from './on-changes.component'; + +@Component({ + selector: 'on-changes-parent', + templateUrl: './on-changes-parent.component.html', + styles: ['.parent {background: Lavender;}'] +}) +export class OnChangesParentComponent { + hero: Hero; + power: string; + title = 'OnChanges'; + @ViewChild(OnChangesComponent) childView: OnChangesComponent; + + constructor() { + this.reset(); + } + + reset() { + // new Hero object every time; triggers onChanges + this.hero = new Hero('Windstorm'); + // setting power only triggers onChanges if this value is different + this.power = 'sing'; + if (this.childView) { + this.childView.reset(); + } + } +} diff --git a/aio/content/examples/lifecycle-hooks/src/app/on-changes.component.ts b/aio/content/examples/lifecycle-hooks/src/app/on-changes.component.ts index b6b8ba2f9e..78e601c5a4 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/on-changes.component.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/on-changes.component.ts @@ -1,13 +1,8 @@ /* tslint:disable:forin */ // #docregion -import { - Component, Input, OnChanges, - SimpleChanges, ViewChild -} from '@angular/core'; +import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; -class Hero { - constructor(public name: string) {} -} +import { Hero } from './hero'; @Component({ selector: 'on-changes', @@ -45,27 +40,3 @@ export class OnChangesComponent implements OnChanges { reset() { this.changeLog = []; } } - -@Component({ - selector: 'on-changes-parent', - templateUrl: './on-changes-parent.component.html', - styles: ['.parent {background: Lavender;}'] -}) -export class OnChangesParentComponent { - hero: Hero; - power: string; - title = 'OnChanges'; - @ViewChild(OnChangesComponent) childView: OnChangesComponent; - - constructor() { - this.reset(); - } - - reset() { - // new Hero object every time; triggers onChanges - this.hero = new Hero('Windstorm'); - // setting power only triggers onChanges if this value is different - this.power = 'sing'; - if (this.childView) { this.childView.reset(); } - } -} diff --git a/aio/content/examples/lifecycle-hooks/src/app/peek-a-boo.component.ts b/aio/content/examples/lifecycle-hooks/src/app/peek-a-boo.component.ts index c66e41a6c9..54df001f83 100644 --- a/aio/content/examples/lifecycle-hooks/src/app/peek-a-boo.component.ts +++ b/aio/content/examples/lifecycle-hooks/src/app/peek-a-boo.component.ts @@ -5,31 +5,17 @@ import { AfterContentInit, AfterViewChecked, AfterViewInit, - Directive, + Component, DoCheck, + Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; -import { Component, Input } from '@angular/core'; + import { LoggerService } from './logger.service'; - -let nextId = 1; - -// #docregion ngOnInit -@Directive() -export class PeekABooDirective implements OnInit { - constructor(private logger: LoggerService) { } - - // implement OnInit's `ngOnInit` method - ngOnInit() { this.logIt(`OnInit`); } - - logIt(msg: string) { - this.logger.log(`#${nextId++} ${msg}`); - } -} -// #enddocregion ngOnInit +import { PeekABooDirective } from './peek-a-boo.directive'; @Component({ selector: 'peek-a-boo', diff --git a/aio/content/examples/lifecycle-hooks/src/app/peek-a-boo.directive.ts b/aio/content/examples/lifecycle-hooks/src/app/peek-a-boo.directive.ts new file mode 100644 index 0000000000..29f55b05cc --- /dev/null +++ b/aio/content/examples/lifecycle-hooks/src/app/peek-a-boo.directive.ts @@ -0,0 +1,21 @@ +import { Directive, OnInit } from '@angular/core'; + +import { LoggerService } from './logger.service'; + +let nextId = 1; + +// #docregion ngOnInit +@Directive() +export class PeekABooDirective implements OnInit { + constructor(private logger: LoggerService) { } + + // implement OnInit's `ngOnInit` method + ngOnInit() { + this.logIt(`OnInit`); + } + + logIt(msg: string) { + this.logger.log(`#${nextId++} ${msg}`); + } +} +// #enddocregion ngOnInit diff --git a/aio/content/guide/lifecycle-hooks.md b/aio/content/guide/lifecycle-hooks.md index 66f0df3f1f..a1b65eb6fa 100644 --- a/aio/content/guide/lifecycle-hooks.md +++ b/aio/content/guide/lifecycle-hooks.md @@ -24,7 +24,7 @@ The hooks give you the opportunity to act on a component or directive instance a Each interface defines the prototype for a single hook method, whose name is the interface name prefixed with `ng`. For example, the `OnInit` interface has a hook method named `ngOnInit()`. If you implement this method in your component or directive class, Angular calls it shortly after checking the input properties for that component or directive for the first time. - + You don't have to implement all (or any) of the lifecycle hooks, just the ones you need. @@ -464,7 +464,7 @@ The *AfterView* sample explores the `AfterViewInit()` and `AfterViewChecked()` h Here's a child view that displays a hero's name in an ``: - + The `AfterViewComponent` displays this child view *within its template*: @@ -528,7 +528,7 @@ This time, instead of including the child view within the template, it imports t the `AfterContentComponent`'s parent. The following is the parent's template. - + Notice that the `` tag is tucked between the `` tags. Never put content between a component's element tags *unless you intend to project that content