Skip to content

Commit

Permalink
feat(playground): add AfterViewInit/Checked docs demos
Browse files Browse the repository at this point in the history
  • Loading branch information
Hotell committed May 9, 2016
1 parent 5b8be35 commit 46bffa7
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 0 deletions.
150 changes: 150 additions & 0 deletions playground/app/components/lifecycle/after-view.component.ts
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
*/
7 changes: 7 additions & 0 deletions playground/app/components/lifecycle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ import * as angular from 'angular';
import { provide } from 'ng-metadata/core';
import { DoCheckComponent, DoCheckParentComponent } from './do-check.component';
import { OnChangesComponent, OnChangesParentComponent } from './on-changes.component';
import { AfterViewParentComponent,AfterViewComponent,ChildViewComponent } from './after-view.component';

import { LoggerService } from './logger.service';

export const LifecycleHooksModule = angular.module('lifecyceHooks', [])
.directive(...provide(DoCheckParentComponent))
.directive(...provide(DoCheckComponent))
.directive(...provide(OnChangesParentComponent))
.directive(...provide(OnChangesComponent))
.directive(...provide(AfterViewParentComponent))
.directive(...provide(AfterViewComponent))
.directive(...provide(ChildViewComponent))
.service( ...provide( LoggerService ) )
.name;
40 changes: 40 additions & 0 deletions playground/app/components/lifecycle/logger.service.ts
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
*/
13 changes: 13 additions & 0 deletions playground/app/components/todo-app.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ <h3>check your console logs mate!</h3>

<h3>Docs examples:</h3>

<!--LC HOOKS-->
<section class="demo-content">
<button
class="mdl-button mdl-js-button mdl-button--accent"
Expand All @@ -152,6 +153,18 @@ <h3>Docs examples:</h3>
</div>
</section>

<section class="demo-content">
<button
class="mdl-button mdl-js-button mdl-button--accent"
ng-click="$ctrl.showLcAfterView=!$ctrl.showLcAfterView">
{{ $ctrl.showLcAfterView ? 'hide' : 'show'}} <code>AfterViewInit/AfterViewChecked</code> LC example
</button>
<div ng-if="$ctrl.showLcAfterView">
<after-view-parent></after-view-parent>
</div>
</section>

<!--CHANGE DETECTOR REF-->
<section class="demo-content">
<button
class="mdl-button mdl-js-button mdl-button--accent"
Expand Down
5 changes: 5 additions & 0 deletions playground/style.css
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);
Expand Down

0 comments on commit 46bffa7

Please sign in to comment.