-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(playground): add AfterViewInit/Checked docs demos
- Loading branch information
Showing
5 changed files
with
215 additions
and
0 deletions.
There are no files selected for viewing
150 changes: 150 additions & 0 deletions
150
playground/app/components/lifecycle/after-view.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { AfterViewChecked, AfterViewInit, Component, ViewChild, Inject, Host, forwardRef } from 'ng-metadata/core'; | ||
|
||
import { NgTimeout } from '../../shared/index'; | ||
import { LoggerService } from './logger.service'; | ||
|
||
////////////////// | ||
@Component({ | ||
selector: 'my-child', | ||
template: '<input ng-model="$ctrl.hero" ng-change="$ctrl.notifyParent()" ng-blur="$ctrl.notifyParent()">' | ||
}) | ||
export class ChildViewComponent { | ||
hero = 'Magneta'; | ||
|
||
constructor( | ||
// we need to use forwardRef because the three hierarchy | ||
@Host() @Inject( forwardRef( ()=>AfterViewComponent ) ) private afterViewCmp: AfterViewComponent | ||
) {} | ||
|
||
notifyParent() { | ||
// NOTE: we have to manually notify parent, in Angular 2 this is done by the framework automatically | ||
// in Angular one #ngAfterViewChecked from parent will be automatically called only during child instantiation/removal | ||
this.afterViewCmp.ngAfterViewChecked() | ||
} | ||
} | ||
|
||
////////////////////// | ||
@Component({ | ||
selector: 'after-view', | ||
template: ` | ||
<button ng-click="$ctrl.toggleChild()">Toggle Child</button> | ||
<div>-- child view begins --</div> | ||
<my-child ng-if="$ctrl.show"></my-child> | ||
<div>-- child view ends --</div> | ||
<p ng-if="$ctrl.comment" class="comment"> | ||
{{$ctrl.comment}} | ||
</p> | ||
`, | ||
|
||
directives: [ ChildViewComponent ] | ||
}) | ||
export class AfterViewComponent implements AfterViewChecked, AfterViewInit { | ||
|
||
private prevHero = ''; | ||
comment = ''; | ||
show = true; | ||
|
||
// Query for a VIEW child of type `ChildViewComponent` | ||
@ViewChild( ChildViewComponent ) viewChild: ChildViewComponent; | ||
|
||
constructor( private $timeout: NgTimeout, private logger: LoggerService ) { | ||
this.logIt('AfterView constructor'); | ||
} | ||
|
||
ngAfterViewInit() { | ||
// viewChild is set after the view has been initialized | ||
this.logIt('AfterViewInit'); | ||
this.doSomething(); | ||
} | ||
|
||
ngAfterViewChecked() { | ||
// if(!this.viewChild) return; | ||
const vc = this.viewChild; | ||
|
||
// viewChild is updated after the view has been checked | ||
if (vc && this.prevHero === vc.hero) { | ||
this.logIt('AfterViewChecked (no change)'); | ||
} else { | ||
this.prevHero = vc && vc.hero; | ||
this.logIt('AfterViewChecked'); | ||
this.doSomething(); | ||
} | ||
} | ||
|
||
toggleChild(){ | ||
this.show = !this.show; | ||
} | ||
|
||
// This surrogate for real business logic sets the `comment` | ||
private doSomething() { | ||
if(!this.viewChild) return; | ||
|
||
let c = this.viewChild.hero.length > 10 ? `That's a long name` : ''; | ||
if (c !== this.comment) { | ||
// Wait a tick because the component's view has already been checked | ||
this.$timeout(() => this.comment = c, 0); | ||
} | ||
} | ||
|
||
private logIt(method:string){ | ||
const vc = this.viewChild; | ||
let message = `${method}: ${vc ? vc.hero : 'no'} child view`; | ||
this.logger.log(message); | ||
} | ||
|
||
} | ||
|
||
////////////// | ||
@Component({ | ||
selector: 'after-view-parent', | ||
template: ` | ||
<div class="parent"> | ||
<h2>AfterView</h2> | ||
<after-view ng-if="$ctrl.show"></after-view> | ||
<h4>-- AfterView Logs --</h4> | ||
<p> | ||
<button ng-click="$ctrl.reset()">Reset</button> | ||
</p> | ||
<div ng-repeat="msg in $ctrl.logs track by $index">{{msg}}</div> | ||
</div> | ||
<style>after-view-parent > .parent {background: burlywood}</style> | ||
`, | ||
providers:[ LoggerService ], | ||
directives: [ AfterViewComponent ] | ||
}) | ||
export class AfterViewParentComponent { | ||
logs: string[]; | ||
show = true; | ||
|
||
constructor( | ||
private $timeout: NgTimeout, | ||
private logger: LoggerService | ||
) { | ||
this.logs = logger.logs; | ||
} | ||
|
||
reset() { | ||
this._emptyLog(); | ||
|
||
// quickly remove and reload AfterViewComponent which recreates it | ||
this.show = false; | ||
this.$timeout( () => this.show = true, 0 ) | ||
} | ||
|
||
ngOnDestroy(){ | ||
this._emptyLog(); | ||
} | ||
|
||
private _emptyLog(){ this.logs.length = 0 } | ||
|
||
} | ||
|
||
|
||
/* | ||
Copyright 2016 Google Inc. All Rights Reserved. | ||
Use of this source code is governed by an MIT-style license that | ||
can be found in the LICENSE file at http://angular.io/license | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { Injectable } from 'ng-metadata/core'; | ||
import { NgTimeout } from '../../shared/index'; | ||
|
||
|
||
@Injectable() | ||
export class LoggerService { | ||
logs: string[] = []; | ||
prevMsg = ''; | ||
prevMsgCount = 1; | ||
|
||
constructor( private $timeout: NgTimeout ) {} | ||
|
||
log( msg: string ) { | ||
if ( msg === this.prevMsg ) { | ||
// Repeat message; update last log entry with count. | ||
this.logs[ this.logs.length - 1 ] = msg + ` (${this.prevMsgCount += 1}x)`; | ||
} else { | ||
// New message; log it. | ||
this.prevMsg = msg; | ||
this.prevMsgCount = 1; | ||
this.logs.push( msg ); | ||
} | ||
} | ||
|
||
clear() { this.logs.length = 0; } | ||
|
||
// schedules a view refresh to ensure display catches up | ||
tick() { | ||
this.$timeout( () => { | ||
console.log('tick') | ||
}, 0 ); | ||
} | ||
} | ||
|
||
|
||
/* | ||
Copyright 2016 Google Inc. All Rights Reserved. | ||
Use of this source code is governed by an MIT-style license that | ||
can be found in the LICENSE file at http://angular.io/license | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,8 @@ | ||
.comment { | ||
color: red; | ||
font-style: italic; | ||
} | ||
|
||
.demo-container { | ||
max-width: 1600px; | ||
width: calc(100% - 16px); | ||
|