/* tslint:disable:forin */ import { Component, ContentChildren, Directive, ElementRef, EventEmitter, Injectable, Input, Output, Optional, HostBinding, HostListener, OnInit, OnChanges, OnDestroy, Pipe, PipeTransform, Renderer, SimpleChange } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/of'; import 'rxjs/add/operator/delay'; ////////// The App: Services and Components for the tests. ////////////// export class Hero { name: string; } ////////// Services /////////////// // #docregion FancyService @Injectable() export class FancyService { protected value: string = 'real value'; getValue() { return this.value; } setValue(value: string) { this.value = value; } getAsyncValue() { return Promise.resolve('async value'); } getObservableValue() { return Observable.of('observable value'); } getTimeoutValue() { return new Promise((resolve) => { setTimeout(() => { resolve('timeout value'); }, 10); }); } getObservableDelayValue() { return Observable.of('observable delay value').delay(10); } } // #enddocregion FancyService // #docregion DependentService @Injectable() export class DependentService { constructor(private dependentService: FancyService) { } getValue() { return this.dependentService.getValue(); } } // #enddocregion DependentService /////////// Pipe //////////////// /* * Reverse the input string. */ // #docregion ReversePipe @Pipe({ name: 'reverse' }) export class ReversePipe implements PipeTransform { transform(s: string) { let r = ''; for (let i = s.length; i; ) { r += s[--i]; }; return r; } } // #enddocregion ReversePipe //////////// Components ///////////// @Component({ selector: 'bank-account', template: ` Bank Name: {{bank}} Account Id: {{id}} ` }) export class BankAccountComponent { @Input() bank: string; @Input('account') id: string; constructor(private renderer: Renderer, private el: ElementRef ) { renderer.setElementProperty(el.nativeElement, 'customProperty', true); } } /** A component with attributes, styles, classes, and property setting */ @Component({ selector: 'bank-account-parent', template: ` ` }) export class BankAccountParentComponent { width = 200; color = 'red'; isClosed = true; } // #docregion ButtonComp @Component({ selector: 'button-comp', template: ` {{message}}` }) export class ButtonComponent { isOn = false; clicked() { this.isOn = !this.isOn; } get message() { return `The light is ${this.isOn ? 'On' : 'Off'}`; } } // #enddocregion ButtonComp @Component({ selector: 'child-1', template: `Child-1({{text}})` }) export class Child1Component { @Input() text = 'Original'; } @Component({ selector: 'child-2', template: '
Child-2({{text}})
' }) export class Child2Component { @Input() text: string; } @Component({ selector: 'child-3', template: '
Child-3({{text}})
' }) export class Child3Component { @Input() text: string; } @Component({ selector: 'input-comp', template: `` }) export class InputComponent { name = 'John'; } /* Prefer this metadata syntax */ // @Directive({ // selector: 'input[value]', // host: { // '[value]': 'value', // '(input)': 'valueChange.next($event.target.value)' // }, // inputs: ['value'], // outputs: ['valueChange'] // }) // export class InputValueBinderDirective { // value: any; // valueChange: EventEmitter = new EventEmitter(); // } // As the style-guide recommends @Directive({ selector: 'input[value]' }) export class InputValueBinderDirective { @HostBinding() @Input() value: any; @Output() valueChange: EventEmitter = new EventEmitter(); @HostListener('input', ['$event.target.value']) onInput(value: any) { this.valueChange.next(value); } } @Component({ selector: 'input-value-comp', template: ` Name: {{name}} ` }) export class InputValueBinderComponent { name = 'Sally'; // initial value } @Component({ selector: 'parent-comp', template: `Parent()` }) export class ParentComponent { } @Component({ selector: 'io-comp', template: `
Original {{hero.name}}
` }) export class IoComponent { @Input() hero: Hero; @Output() selected = new EventEmitter(); click() { this.selected.emit(this.hero); } } @Component({ selector: 'io-parent-comp', template: `

Click to select a hero

The selected hero is {{selectedHero.name}}

` }) export class IoParentComponent { heroes: Hero[] = [ {name: 'Bob'}, {name: 'Carol'}, {name: 'Ted'}, {name: 'Alice'} ]; selectedHero: Hero; onSelect(hero: Hero) { this.selectedHero = hero; } } @Component({ selector: 'my-if-comp', template: `MyIf(More)` }) export class MyIfComponent { showMore = false; } @Component({ selector: 'my-service-comp', template: `injected value: {{fancyService.value}}`, providers: [FancyService] }) export class TestProvidersComponent { constructor(private fancyService: FancyService) {} } @Component({ selector: 'my-service-comp', template: `injected value: {{fancyService.value}}`, viewProviders: [FancyService] }) export class TestViewProvidersComponent { constructor(private fancyService: FancyService) {} } @Component({ moduleId: module.id, selector: 'external-template-comp', templateUrl: 'bag-external-template.html' }) export class ExternalTemplateComponent implements OnInit { serviceValue: string; constructor(@Optional() private service: FancyService) { } ngOnInit() { if (this.service) { this.serviceValue = this.service.getValue(); } } } @Component({ selector: 'comp-w-ext-comp', template: `

comp-w-ext-comp

` }) export class InnerCompWithExternalTemplateComponent { } @Component({ moduleId: module.id, selector: 'bad-template-comp', templateUrl: 'non-existant.html' }) export class BadTemplateUrlComponent { } @Component({selector: 'needs-content', template: ''}) export class NeedsContentComponent { // children with #content local variable @ContentChildren('content') children: any; } ///////// MyIfChildComp //////// @Component({ selector: 'my-if-child-1', template: `

MyIfChildComp

Change log:

{{i + 1}} - {{log}}
` }) export class MyIfChildComponent implements OnInit, OnChanges, OnDestroy { @Input() value = ''; @Output() valueChange = new EventEmitter(); get childValue() { return this.value; } set childValue(v: string) { if (this.value === v) { return; } this.value = v; this.valueChange.emit(v); } changeLog: string[] = []; ngOnInitCalled = false; ngOnChangesCounter = 0; ngOnDestroyCalled = false; ngOnInit() { this.ngOnInitCalled = true; this.changeLog.push('ngOnInit called'); } ngOnDestroy() { this.ngOnDestroyCalled = true; this.changeLog.push('ngOnDestroy called'); } ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { for (let propName in changes) { this.ngOnChangesCounter += 1; let prop = changes[propName]; let cur = JSON.stringify(prop.currentValue); let prev = JSON.stringify(prop.previousValue); this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`); } } } ///////// MyIfParentComp //////// @Component({ selector: 'my-if-parent-comp', template: `

MyIfParentComp


` }) export class MyIfParentComponent implements OnInit { ngOnInitCalled = false; parentValue = 'Hello, World'; showChild = false; toggleLabel = 'Unknown'; ngOnInit() { this.ngOnInitCalled = true; this.clicked(); } clicked() { this.showChild = !this.showChild; this.toggleLabel = this.showChild ? 'Close' : 'Show'; } } @Component({ selector: 'reverse-pipe-comp', template: ` {{text | reverse}} ` }) export class ReversePipeComponent { text = 'my dog has fleas.'; } @Component({template: '
Replace Me
'}) export class ShellComponent { } @Component({ selector: 'bag-comp', template: `

Specs Bag


Input/Output Component


External Template Component


Component With External Template Component


Reverse Pipe


InputValueBinder Directive


Button Component


Needs Content

!
` }) export class BagComponent { } //////// Aggregations //////////// export const bagDeclarations = [ BagComponent, BankAccountComponent, BankAccountParentComponent, ButtonComponent, Child1Component, Child2Component, Child3Component, ExternalTemplateComponent, InnerCompWithExternalTemplateComponent, InputComponent, InputValueBinderDirective, InputValueBinderComponent, IoComponent, IoParentComponent, MyIfComponent, MyIfChildComponent, MyIfParentComponent, NeedsContentComponent, ParentComponent, TestProvidersComponent, TestViewProvidersComponent, ReversePipe, ReversePipeComponent, ShellComponent ]; export const bagProviders = [DependentService, FancyService]; //////////////////// //////////// import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; @NgModule({ imports: [BrowserModule, FormsModule], declarations: bagDeclarations, providers: bagProviders, entryComponents: [BagComponent], bootstrap: [BagComponent] }) export class BagModule { }