docs: imrpove accessibility of lifecycle hooks example (#41071)
PR Close #41071
This commit is contained in:
parent
3ccad85b01
commit
695b72a972
|
@ -86,7 +86,7 @@ describe('Lifecycle hooks', () => {
|
|||
const parentEle = element(by.tagName('after-view-parent'));
|
||||
const buttonEle = parentEle.element(by.tagName('button')); // Reset
|
||||
const commentEle = parentEle.element(by.className('comment'));
|
||||
const logEles = parentEle.all(by.css('h4 ~ div'));
|
||||
const logEles = parentEle.all(by.css('h3 ~ div'));
|
||||
const childViewInputEle = parentEle.element(by.css('app-child-view input'));
|
||||
let logCount: number;
|
||||
|
||||
|
@ -113,7 +113,7 @@ describe('Lifecycle hooks', () => {
|
|||
const parentEle = element(by.tagName('after-content-parent'));
|
||||
const buttonEle = parentEle.element(by.tagName('button')); // Reset
|
||||
const commentEle = parentEle.element(by.className('comment'));
|
||||
const logEles = parentEle.all(by.css('h4 ~ div'));
|
||||
const logEles = parentEle.all(by.css('h3 ~ div'));
|
||||
const childViewInputEle = parentEle.element(by.css('app-child input'));
|
||||
let logCount = await logEles.count();
|
||||
|
||||
|
@ -136,8 +136,8 @@ describe('Lifecycle hooks', () => {
|
|||
const inputEle = element(by.css('spy-parent input'));
|
||||
const addHeroButtonEle = element(by.cssContainingText('spy-parent button', 'Add Hero'));
|
||||
const resetHeroesButtonEle = element(by.cssContainingText('spy-parent button', 'Reset Heroes'));
|
||||
const heroEles = element.all(by.css('spy-parent div[appSpy'));
|
||||
const logEles = element.all(by.css('spy-parent h4 ~ div'));
|
||||
const heroEles = element.all(by.css('spy-parent div p'));
|
||||
const logEles = element.all(by.css('spy-parent h3 ~ div'));
|
||||
|
||||
expect(await heroEles.count()).toBe(2, 'should have two heroes displayed');
|
||||
expect(await logEles.count()).toBe(2, 'should have two log entries');
|
||||
|
@ -156,18 +156,19 @@ describe('Lifecycle hooks', () => {
|
|||
it('should support "spy counter"', async () => {
|
||||
const updateCounterButtonEle = element(by.cssContainingText('counter-parent button', 'Update'));
|
||||
const resetCounterButtonEle = element(by.cssContainingText('counter-parent button', 'Reset'));
|
||||
const textEle = element(by.css('counter-parent app-counter > div'));
|
||||
const logEles = element.all(by.css('counter-parent h4 ~ div'));
|
||||
const textEle = element(by.css('counter-parent app-counter p'));
|
||||
const logEles = element.all(by.css('counter-parent .info .log'));
|
||||
|
||||
expect(await textEle.getText()).toContain('Counter = 0');
|
||||
expect(await logEles.count()).toBe(2, 'should start with two log entries');
|
||||
expect(await logEles.count()).toBe(3, 'should start with one change log and two lifecycle log entries, including reset');
|
||||
|
||||
await updateCounterButtonEle.click();
|
||||
expect(await textEle.getText()).toContain('Counter = 1');
|
||||
expect(await logEles.count()).toBe(3, 'should now have 3 log entries');
|
||||
expect(await logEles.count()).toBe(5, 'should now have 2 change log entries and 3 lifecycle log entries, including reset');
|
||||
|
||||
await resetCounterButtonEle.click();
|
||||
expect(await textEle.getText()).toContain('Counter = 0');
|
||||
expect(await logEles.count()).toBe(7, 'should now have 7 log entries - 3 prev + 1 reset + 2 destroy + 1 init');
|
||||
expect(await logEles.count()).toBe(8, 'should now have 8 log entries - 1 change log + 2 reset + 2 destroy + 3 init');
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,12 +16,13 @@ import { LoggerService } from './logger.service';
|
|||
// #enddocregion parent-template
|
||||
+ `</div>
|
||||
|
||||
<h4>-- AfterContent Logs --</h4>
|
||||
<p><button (click)="reset()">Reset</button></p>
|
||||
<div *ngFor="let msg of logger.logs">{{msg}}</div>
|
||||
<div class="info">
|
||||
<h3>AfterContent Logs</h3>
|
||||
<button (click)="reset()">Reset</button>
|
||||
<div *ngFor="let msg of logger.logs" class="log">{{msg}}</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
styles: ['.parent {background: burlywood}'],
|
||||
providers: [LoggerService]
|
||||
})
|
||||
export class AfterContentParentComponent {
|
||||
|
|
|
@ -9,9 +9,9 @@ import { LoggerService } from './logger.service';
|
|||
selector: 'after-content',
|
||||
// #docregion template
|
||||
template: `
|
||||
<div>-- projected content begins --</div>
|
||||
<div>projected content begins</div>
|
||||
<ng-content></ng-content>
|
||||
<div>-- projected content ends --</div>`
|
||||
<div>projected content ends</div>`
|
||||
// #enddocregion template
|
||||
+ `
|
||||
<p *ngIf="comment" class="comment">
|
||||
|
|
|
@ -5,17 +5,16 @@ import { LoggerService } from './logger.service';
|
|||
@Component({
|
||||
selector: 'after-view-parent',
|
||||
template: `
|
||||
<div class="parent">
|
||||
<h2>AfterView</h2>
|
||||
|
||||
<after-view *ngIf="show"></after-view>
|
||||
|
||||
<h4>-- AfterView Logs --</h4>
|
||||
<p><button (click)="reset()">Reset</button></p>
|
||||
<div *ngFor="let msg of logger.logs">{{msg}}</div>
|
||||
<div class="info">
|
||||
<h3>AfterView Logs</h3>
|
||||
<button (click)="reset()">Reset</button>
|
||||
<div *ngFor="let msg of logger.logs" class="log">{{msg}}</div>
|
||||
</div>
|
||||
`,
|
||||
styles: ['.parent {background: burlywood}'],
|
||||
providers: [LoggerService]
|
||||
})
|
||||
export class AfterViewParentComponent {
|
||||
|
|
|
@ -9,9 +9,9 @@ import { LoggerService } from './logger.service';
|
|||
selector: 'after-view',
|
||||
// #docregion template
|
||||
template: `
|
||||
<div>-- child view begins --</div>
|
||||
<div>child view begins</div>
|
||||
<app-child-view></app-child-view>
|
||||
<div>-- child view ends --</div>`
|
||||
<div>child view ends</div>`
|
||||
// #enddocregion template
|
||||
+ `
|
||||
<p *ngIf="comment" class="comment">
|
||||
|
|
|
@ -1,36 +1,42 @@
|
|||
<a id="top"></a>
|
||||
<h1>Component Lifecycle Hooks</h1>
|
||||
<a href="#hooks">Peek-a-boo: (most) lifecycle hooks</a><br>
|
||||
<a href="#spy">Spy: directive with OnInit & OnDestroy</a><br>
|
||||
<a href="#onchanges">OnChanges</a><br>
|
||||
<a href="#docheck">DoCheck</a><br>
|
||||
<a href="#after-view">AfterViewInit & AfterViewChecked</a><br>
|
||||
<a href="#after-content">AfterContentInit & AfterContentChecked</a><br>
|
||||
<a href="#counter">Counter: OnChanges + Spy directive</a><br>
|
||||
<h1>Lifecycle Hooks</h1>
|
||||
<a href="#hooks">Peek-a-boo: (most) lifecycle hooks</a>
|
||||
<a href="#spy">Spy: directive with OnInit & OnDestroy</a>
|
||||
<a href="#onchanges">OnChanges</a>
|
||||
<a href="#docheck">DoCheck</a>
|
||||
<a href="#after-view">AfterViewInit & AfterViewChecked</a>
|
||||
<a href="#after-content">AfterContentInit & AfterContentChecked</a>
|
||||
<a href="#counter">Counter: OnChanges + Spy directive</a>
|
||||
|
||||
<a id="hooks"></a>
|
||||
<peek-a-boo-parent></peek-a-boo-parent>
|
||||
<a href="#top">back to top</a>
|
||||
<hr />
|
||||
|
||||
<a id="spy"></a>
|
||||
<spy-parent></spy-parent>
|
||||
<a href="#top">back to top</a>
|
||||
<hr />
|
||||
|
||||
<a id="onchanges"></a>
|
||||
<on-changes-parent></on-changes-parent>
|
||||
<a href="#top">back to top</a>
|
||||
<hr />
|
||||
|
||||
<a id="docheck"></a>
|
||||
<do-check-parent></do-check-parent>
|
||||
<a href="#top">back to top</a>
|
||||
<hr />
|
||||
|
||||
<a id="after-view"></a>
|
||||
<after-view-parent></after-view-parent>
|
||||
<a href="#top">back to top</a>
|
||||
<hr />
|
||||
|
||||
<a id="after-content"></a>
|
||||
<after-content-parent></after-content-parent>
|
||||
<a href="#top">back to top</a>
|
||||
<hr />
|
||||
|
||||
<a id="counter"></a>
|
||||
<counter-parent></counter-parent>
|
||||
|
|
|
@ -3,7 +3,8 @@ import { Component } from '@angular/core';
|
|||
// #docregion child-view
|
||||
@Component({
|
||||
selector: 'app-child-view',
|
||||
template: '<input [(ngModel)]="hero">'
|
||||
template: `<label for="hero-name">Hero name: </label>
|
||||
<input type="text" id="hero-name" [(ngModel)]="hero">`
|
||||
})
|
||||
export class ChildViewComponent {
|
||||
hero = 'Magneta';
|
||||
|
|
|
@ -2,7 +2,8 @@ import { Component } from '@angular/core';
|
|||
|
||||
@Component({
|
||||
selector: 'app-child',
|
||||
template: '<input [(ngModel)]="hero">'
|
||||
template: `<label for="hero-name">Hero name: </label>
|
||||
<input type="text" id="hero-name" [(ngModel)]="hero">`
|
||||
})
|
||||
export class ChildComponent {
|
||||
hero = 'Magneta';
|
||||
|
|
|
@ -5,7 +5,6 @@ import { LoggerService } from './logger.service';
|
|||
@Component({
|
||||
selector: 'counter-parent',
|
||||
template: `
|
||||
<div class="parent">
|
||||
<h2>Counter Spy</h2>
|
||||
|
||||
<button (click)="updateCounter()">Update counter</button>
|
||||
|
@ -13,11 +12,11 @@ import { LoggerService } from './logger.service';
|
|||
|
||||
<app-counter [counter]="value"></app-counter>
|
||||
|
||||
<h4>-- Spy Lifecycle Hook Log --</h4>
|
||||
<div *ngFor="let msg of spyLog">{{msg}}</div>
|
||||
<div class="info">
|
||||
<h3>Spy Lifecycle Hook Log</h3>
|
||||
<div *ngFor="let msg of spyLog" class="log">{{msg}}</div>
|
||||
</div>
|
||||
`,
|
||||
styles: ['.parent {background: gold;}'],
|
||||
providers: [LoggerService]
|
||||
})
|
||||
export class CounterParentComponent {
|
||||
|
@ -38,7 +37,7 @@ export class CounterParentComponent {
|
|||
}
|
||||
|
||||
reset() {
|
||||
this.logger.log('-- reset --');
|
||||
this.logger.log('reset');
|
||||
this.value = 0;
|
||||
this.logger.tick();
|
||||
}
|
||||
|
|
|
@ -7,14 +7,13 @@ import {
|
|||
@Component({
|
||||
selector: 'app-counter',
|
||||
template: `
|
||||
<div class="counter">
|
||||
Counter = {{counter}}
|
||||
<p>Counter = {{counter}}</p>
|
||||
|
||||
<h5>-- Counter Change Log --</h5>
|
||||
<div *ngFor="let chg of changeLog" appSpy>{{chg}}</div>
|
||||
<div class="info">
|
||||
<h3>Counter Change Log</h3>
|
||||
<div *ngFor="let chg of changeLog" appSpy class="log">{{chg}}</div>
|
||||
</div>
|
||||
`,
|
||||
styles: ['.counter {background: LightYellow; padding: 8px; margin-top: 8px}']
|
||||
`
|
||||
})
|
||||
export class MyCounterComponent implements OnChanges {
|
||||
@Input() counter: number;
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<div class="parent">
|
||||
<h2>{{title}}</h2>
|
||||
|
||||
<table>
|
||||
<tr><td>Power: </td><td><input [(ngModel)]="power"></td></tr>
|
||||
<tr><td>Hero.name: </td><td><input [(ngModel)]="hero.name"></td></tr>
|
||||
</table>
|
||||
<p><button (click)="reset()">Reset Log</button></p>
|
||||
<label for="power-input"><label>Power: </label>
|
||||
<input type="text" id="power-input" [(ngModel)]="power">
|
||||
<label for="hero-name">Hero.name: </label>
|
||||
<input type="text" id="hero-name" [(ngModel)]="hero.name">
|
||||
<button (click)="reset()">Reset Log</button>
|
||||
|
||||
<do-check [hero]="hero" [power]="power"></do-check>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@ import { Hero } from './hero';
|
|||
|
||||
@Component({
|
||||
selector: 'do-check-parent',
|
||||
templateUrl: './do-check-parent.component.html',
|
||||
styles: ['.parent {background: Lavender}']
|
||||
templateUrl: './do-check-parent.component.html'
|
||||
})
|
||||
export class DoCheckParentComponent {
|
||||
hero: Hero;
|
||||
|
|
|
@ -7,17 +7,13 @@ import { Hero } from './hero';
|
|||
@Component({
|
||||
selector: 'do-check',
|
||||
template: `
|
||||
<div class="hero">
|
||||
<div class="info">
|
||||
<p>{{hero.name}} can {{power}}</p>
|
||||
|
||||
<h4>-- Change Log --</h4>
|
||||
<div *ngFor="let chg of changeLog">{{chg}}</div>
|
||||
<h3>Change Log</h3>
|
||||
<div *ngFor="let chg of changeLog" class="log">{{chg}}</div>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
'.hero {background: LightYellow; padding: 8px; margin-top: 8px}',
|
||||
'p {background: Yellow; padding: 8px; margin-top: 8px}'
|
||||
]
|
||||
`
|
||||
})
|
||||
export class DoCheckComponent implements DoCheck {
|
||||
@Input() hero: Hero;
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
<div class="parent">
|
||||
<h2>{{title}}</h2>
|
||||
<label for="power-input">Power: </label>
|
||||
<input type="text" id="power-input" [(ngModel)]="power">
|
||||
<label for="hero-name"> Hero.name: </label>
|
||||
<input type="text" id="hero-name" [(ngModel)]="hero.name">
|
||||
|
||||
<table>
|
||||
<tr><td>Power: </td><td><input [(ngModel)]="power"></td></tr>
|
||||
<tr><td>Hero.name: </td><td><input [(ngModel)]="hero.name"></td></tr>
|
||||
</table>
|
||||
<p><button (click)="reset()">Reset Log</button></p>
|
||||
<button (click)="reset()">Reset Log</button>
|
||||
|
||||
<!-- #docregion on-changes -->
|
||||
<on-changes [hero]="hero" [power]="power"></on-changes>
|
||||
<!-- #enddocregion on-changes -->
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,7 @@ import { OnChangesComponent } from './on-changes.component';
|
|||
@Component({
|
||||
selector: 'on-changes-parent',
|
||||
templateUrl: './on-changes-parent.component.html',
|
||||
styles: ['.parent {background: Lavender;}']
|
||||
styles: ['']
|
||||
})
|
||||
export class OnChangesParentComponent {
|
||||
hero: Hero;
|
||||
|
|
|
@ -7,17 +7,13 @@ import { Hero } from './hero';
|
|||
@Component({
|
||||
selector: 'on-changes',
|
||||
template: `
|
||||
<div class="hero">
|
||||
<div class="info">
|
||||
<p>{{hero.name}} can {{power}}</p>
|
||||
|
||||
<h4>-- Change Log --</h4>
|
||||
<div *ngFor="let chg of changeLog">{{chg}}</div>
|
||||
<h3>Change Log</h3>
|
||||
<div *ngFor="let chg of changeLog" class="log">{{chg}}</div>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
'.hero {background: LightYellow; padding: 8px; margin-top: 8px}',
|
||||
'p {background: Yellow; padding: 8px; margin-top: 8px}'
|
||||
]
|
||||
`
|
||||
})
|
||||
export class OnChangesComponent implements OnChanges {
|
||||
// #docregion inputs
|
||||
|
|
|
@ -6,6 +6,7 @@ import { LoggerService } from './logger.service';
|
|||
@Component({
|
||||
selector: 'peek-a-boo-parent',
|
||||
template: `
|
||||
<hr />
|
||||
<div class="parent">
|
||||
<h2>Peek-A-Boo</h2>
|
||||
|
||||
|
@ -14,14 +15,14 @@ import { LoggerService } from './logger.service';
|
|||
</button>
|
||||
<button (click)="updateHero()" [hidden]="!hasChild">Update Hero</button>
|
||||
|
||||
<peek-a-boo *ngIf="hasChild" [name]="heroName">
|
||||
</peek-a-boo>
|
||||
<div class="info">
|
||||
<peek-a-boo *ngIf="hasChild" [name]="heroName"></peek-a-boo>
|
||||
|
||||
<h4>-- Lifecycle Hook Log --</h4>
|
||||
<div *ngFor="let msg of hookLog">{{msg}}</div>
|
||||
<h3>Lifecycle Hook Log</h3>
|
||||
<div *ngFor="let msg of hookLog" class="log">{{msg}}</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
styles: ['.parent {background: moccasin}'],
|
||||
providers: [ LoggerService ]
|
||||
})
|
||||
export class PeekABooParentComponent {
|
||||
|
|
|
@ -19,8 +19,7 @@ import { PeekABooDirective } from './peek-a-boo.directive';
|
|||
|
||||
@Component({
|
||||
selector: 'peek-a-boo',
|
||||
template: '<p>Now you see my hero, {{name}}</p>',
|
||||
styles: ['p {background: LightYellow; padding: 8px}']
|
||||
template: '<p>Now you see my hero, {{name}}</p>'
|
||||
})
|
||||
// Don't HAVE to mention the Lifecycle Hook interfaces
|
||||
// unless we want typing and tool support.
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
<div class="parent">
|
||||
<h2>Spy Directive</h2>
|
||||
|
||||
<input [(ngModel)]="newName" (keyup.enter)="addHero()">
|
||||
<label for="hero-name">Hero name: </label>
|
||||
<input type="text" id="hero-name" [(ngModel)]="newName" (keyup.enter)="addHero()">
|
||||
<button (click)="addHero()">Add Hero</button>
|
||||
<button (click)="reset()">Reset Heroes</button>
|
||||
|
||||
<p></p>
|
||||
<div class="info">
|
||||
<!-- #docregion template -->
|
||||
<div *ngFor="let hero of heroes" appSpy class="heroes">
|
||||
<p *ngFor="let hero of heroes" appSpy>
|
||||
{{hero}}
|
||||
</div>
|
||||
</p>
|
||||
<!-- #enddocregion template -->
|
||||
<h4>-- Spy Lifecycle Hook Log --</h4>
|
||||
<div *ngFor="let msg of logger.logs">{{msg}}</div>
|
||||
|
||||
<h3>Spy Lifecycle Hook Log</h3>
|
||||
<div *ngFor="let msg of logger.logs" class="log">{{msg}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,10 +6,6 @@ import { LoggerService } from './logger.service';
|
|||
@Component({
|
||||
selector: 'spy-parent',
|
||||
templateUrl: './spy.component.html',
|
||||
styles: [
|
||||
'.parent {background: khaki;}',
|
||||
'.heroes {background: LightYellow; padding: 0 8px}'
|
||||
],
|
||||
providers: [LoggerService]
|
||||
})
|
||||
export class SpyParentComponent {
|
||||
|
@ -31,7 +27,7 @@ export class SpyParentComponent {
|
|||
this.logger.tick();
|
||||
}
|
||||
reset() {
|
||||
this.logger.log('-- reset --');
|
||||
this.logger.log('reset');
|
||||
this.heroes = [];
|
||||
this.logger.tick();
|
||||
}
|
||||
|
|
|
@ -1,13 +1,61 @@
|
|||
.parent {
|
||||
color: #666;
|
||||
margin: 14px 0;
|
||||
padding: 8px;
|
||||
padding: 2rem 0;
|
||||
}
|
||||
input {
|
||||
margin: 4px;
|
||||
padding: 4px;
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.comment {
|
||||
color: red;
|
||||
color: #890000;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.log {
|
||||
background-color: #e4e4e4;
|
||||
padding: .25rem;
|
||||
}
|
||||
|
||||
.info {
|
||||
background: #fff4f4;
|
||||
padding: .75rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: .25rem;
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding-bottom: .5rem;
|
||||
font-size: 1.1rem;
|
||||
color: #264d73
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a[href="#top"] {
|
||||
margin: 1rem 0;
|
||||
padding: .5rem;
|
||||
background-color: #264d73;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
a[href="#top"]:hover {
|
||||
background-color:#eaeaea;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a[href="#top"]:active {
|
||||
background-color: black;
|
||||
color: #eaeaea;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-bottom: 1rem;
|
||||
margin-top: .5rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue