Merge remote-tracking branch 'origin/master'
# Conflicts: # public/docs/_examples/cb-component-communication/e2e-spec.ts # public/docs/_examples/cb-component-communication/ts/app/app.component.ts # public/docs/_examples/dependency-injection/ts/app/main.1.ts # public/docs/ts/latest/tutorial/toh-pt1.jade # public/docs/ts/latest/tutorial/toh-pt2.jade # public/docs/ts/latest/tutorial/toh-pt3.jade # public/docs/ts/latest/tutorial/toh-pt4.jade # public/docs/ts/latest/tutorial/toh-pt5.jade
This commit is contained in:
commit
f2dbdb3163
10
gulpfile.js
10
gulpfile.js
|
@ -636,7 +636,15 @@ gulp.task('_zip-examples', function() {
|
||||||
// Linting
|
// Linting
|
||||||
|
|
||||||
gulp.task('lint', function() {
|
gulp.task('lint', function() {
|
||||||
return gulp.src(['./public/docs/_examples/style-guide/ts/**/*.ts', '!./public/docs/_examples/style-guide/ts/**/*.avoid.ts'])
|
return gulp.src([
|
||||||
|
'./public/docs/_examples/**/*.ts',
|
||||||
|
'!./public/docs/_examples/**/ts-snippets/*.ts',
|
||||||
|
'!./public/docs/_examples/style-guide/ts/**/*.avoid.ts',
|
||||||
|
'!./public/docs/_examples/**/node_modules/**/*',
|
||||||
|
'!./public/docs/_examples/_protractor/**/*',
|
||||||
|
'!./public/docs/_examples/**/typings/**/*',
|
||||||
|
'!./public/docs/_examples/**/typings-ng1/**/*'
|
||||||
|
])
|
||||||
.pipe(tslint({
|
.pipe(tslint({
|
||||||
rulesDirectory: ['node_modules/codelyzer'],
|
rulesDirectory: ['node_modules/codelyzer'],
|
||||||
configuration: require('./tslint.json')
|
configuration: require('./tslint.json')
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
"browser-sync": "^2.9.3",
|
"browser-sync": "^2.9.3",
|
||||||
"canonical-path": "0.0.2",
|
"canonical-path": "0.0.2",
|
||||||
"cross-spawn": "^4.0.0",
|
"cross-spawn": "^4.0.0",
|
||||||
"codelyzer": "0.0.20",
|
"codelyzer": "0.0.22",
|
||||||
"del": "^2.2.0",
|
"del": "^2.2.0",
|
||||||
"dgeni": "^0.4.0",
|
"dgeni": "^0.4.0",
|
||||||
"dgeni-packages": "^0.13.0",
|
"dgeni-packages": "^0.13.0",
|
||||||
|
|
|
@ -13,7 +13,7 @@ const HEROES = [
|
||||||
export class BackendService {
|
export class BackendService {
|
||||||
constructor(private logger: Logger) {}
|
constructor(private logger: Logger) {}
|
||||||
|
|
||||||
getAll(type:Type) : PromiseLike<any[]>{
|
getAll(type: Type): PromiseLike<any[]> {
|
||||||
if (type === Hero) {
|
if (type === Hero) {
|
||||||
// TODO get from the database
|
// TODO get from the database
|
||||||
return Promise.resolve<Hero[]>(HEROES);
|
return Promise.resolve<Hero[]>(HEROES);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, Input} from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
import { Hero } from './hero';
|
import { Hero } from './hero';
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ export class SalesTaxComponent {
|
||||||
constructor(private salesTaxService: SalesTaxService) { }
|
constructor(private salesTaxService: SalesTaxService) { }
|
||||||
// #enddocregion ctor
|
// #enddocregion ctor
|
||||||
|
|
||||||
getTax(value:string | number){
|
getTax(value: string | number) {
|
||||||
return this.salesTaxService.getVAT(value);
|
return this.salesTaxService.getVAT(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Inject, Injectable } from '@angular/core';
|
import { Inject, Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { TaxRateService } from './tax-rate.service';
|
import { TaxRateService } from './tax-rate.service';
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ import { TaxRateService } from './tax-rate.service';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SalesTaxService {
|
export class SalesTaxService {
|
||||||
constructor(private rateService: TaxRateService) { }
|
constructor(private rateService: TaxRateService) { }
|
||||||
getVAT(value:string | number){
|
getVAT(value: string | number) {
|
||||||
let amount:number;
|
let amount: number;
|
||||||
if (typeof value === "string"){
|
if (typeof value === 'string') {
|
||||||
amount = parseFloat(value);
|
amount = parseFloat(value);
|
||||||
} else {
|
} else {
|
||||||
amount = value;
|
amount = value;
|
||||||
|
|
|
@ -4,6 +4,6 @@ import { Injectable } from '@angular/core';
|
||||||
// #docregion class
|
// #docregion class
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TaxRateService {
|
export class TaxRateService {
|
||||||
getRate(rateName:string){return 0.10;} // always 10% everywhere
|
getRate(rateName: string) {return 0.10; } // always 10% everywhere
|
||||||
}
|
}
|
||||||
// #enddocregion class
|
// #enddocregion class
|
||||||
|
|
|
@ -11,4 +11,4 @@ import { HighlightDirective } from './highlight.directive';
|
||||||
|
|
||||||
export class AppComponent { }
|
export class AppComponent { }
|
||||||
|
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
|
|
@ -14,12 +14,12 @@ import { Directive, ElementRef, Input } from '@angular/core';
|
||||||
export class HighlightDirective {
|
export class HighlightDirective {
|
||||||
|
|
||||||
// #docregion ctor
|
// #docregion ctor
|
||||||
private el:HTMLElement;
|
private el: HTMLElement;
|
||||||
constructor(el: ElementRef) { this.el = el.nativeElement; }
|
constructor(el: ElementRef) { this.el = el.nativeElement; }
|
||||||
// #enddocregion ctor
|
// #enddocregion ctor
|
||||||
|
|
||||||
// #docregion mouse-methods
|
// #docregion mouse-methods
|
||||||
onMouseEnter() { this.highlight("yellow"); }
|
onMouseEnter() { this.highlight('yellow'); }
|
||||||
onMouseLeave() { this.highlight(null); }
|
onMouseLeave() { this.highlight(null); }
|
||||||
|
|
||||||
private highlight(color: string) {
|
private highlight(color: string) {
|
||||||
|
|
|
@ -13,12 +13,12 @@ import { Directive, ElementRef, Input } from '@angular/core';
|
||||||
export class HighlightDirective {
|
export class HighlightDirective {
|
||||||
private _defaultColor = 'red';
|
private _defaultColor = 'red';
|
||||||
private el: HTMLElement;
|
private el: HTMLElement;
|
||||||
|
|
||||||
constructor(el: ElementRef) { this.el = el.nativeElement; }
|
constructor(el: ElementRef) { this.el = el.nativeElement; }
|
||||||
// #enddocregion class-1
|
// #enddocregion class-1
|
||||||
|
|
||||||
// #docregion defaultColor
|
// #docregion defaultColor
|
||||||
@Input() set defaultColor(colorName:string){
|
@Input() set defaultColor(colorName: string){
|
||||||
this._defaultColor = colorName || this._defaultColor;
|
this._defaultColor = colorName || this._defaultColor;
|
||||||
}
|
}
|
||||||
// #enddocregion defaultColor
|
// #enddocregion defaultColor
|
||||||
|
@ -33,7 +33,7 @@ export class HighlightDirective {
|
||||||
// #enddocregion mouse-enter
|
// #enddocregion mouse-enter
|
||||||
onMouseLeave() { this.highlight(null); }
|
onMouseLeave() { this.highlight(null); }
|
||||||
|
|
||||||
private highlight(color:string) {
|
private highlight(color: string) {
|
||||||
this.el.style.backgroundColor = color;
|
this.el.style.backgroundColor = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ describe('Angular 1 to 2 Quick Reference Tests', function () {
|
||||||
|
|
||||||
posterButton.click().then(function () {
|
posterButton.click().then(function () {
|
||||||
testImagesAreDisplayed(isDisplayed);
|
testImagesAreDisplayed(isDisplayed);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMovieRows() {
|
function getMovieRows() {
|
||||||
|
@ -107,7 +107,7 @@ describe('Angular 1 to 2 Quick Reference Tests', function () {
|
||||||
} else {
|
} else {
|
||||||
expect(favoriteHeroLabel.isDisplayed()).toBe(false);
|
expect(favoriteHeroLabel.isDisplayed()).toBe(false);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { StringSafeDatePipe } from './date.pipe';
|
||||||
// #docregion component
|
// #docregion component
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'movie-list',
|
selector: 'movie-list',
|
||||||
templateUrl:'app/movie-list.component.html',
|
templateUrl: 'app/movie-list.component.html',
|
||||||
// #enddocregion component
|
// #enddocregion component
|
||||||
// #docregion style-url
|
// #docregion style-url
|
||||||
styleUrls: ['app/movie-list.component.css'],
|
styleUrls: ['app/movie-list.component.css'],
|
||||||
|
|
|
@ -19,8 +19,8 @@ describe('Component Communication Cookbook Tests', function () {
|
||||||
for (let i = 0; i < _heroNames.length; i++) {
|
for (let i = 0; i < _heroNames.length; i++) {
|
||||||
let childTitle = heroes.get(i).element(by.tagName('h3')).getText();
|
let childTitle = heroes.get(i).element(by.tagName('h3')).getText();
|
||||||
let childDetail = heroes.get(i).element(by.tagName('p')).getText();
|
let childDetail = heroes.get(i).element(by.tagName('p')).getText();
|
||||||
expect(childTitle).toEqual(_heroNames[i] + ' says:')
|
expect(childTitle).toEqual(_heroNames[i] + ' says:');
|
||||||
expect(childDetail).toContain(_masterName)
|
expect(childDetail).toContain(_masterName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// ...
|
// ...
|
||||||
|
@ -37,7 +37,7 @@ describe('Component Communication Cookbook Tests', function () {
|
||||||
let hero = parent.all(by.tagName('name-child')).get(_nonEmptyNameIndex);
|
let hero = parent.all(by.tagName('name-child')).get(_nonEmptyNameIndex);
|
||||||
|
|
||||||
let displayName = hero.element(by.tagName('h3')).getText();
|
let displayName = hero.element(by.tagName('h3')).getText();
|
||||||
expect(displayName).toEqual(_nonEmptyName)
|
expect(displayName).toEqual(_nonEmptyName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should replace empty name with default name', function () {
|
it('should replace empty name with default name', function () {
|
||||||
|
@ -47,7 +47,7 @@ describe('Component Communication Cookbook Tests', function () {
|
||||||
let hero = parent.all(by.tagName('name-child')).get(_emptyNameIndex);
|
let hero = parent.all(by.tagName('name-child')).get(_emptyNameIndex);
|
||||||
|
|
||||||
let displayName = hero.element(by.tagName('h3')).getText();
|
let displayName = hero.element(by.tagName('h3')).getText();
|
||||||
expect(displayName).toEqual(_defaultName)
|
expect(displayName).toEqual(_defaultName);
|
||||||
});
|
});
|
||||||
// ...
|
// ...
|
||||||
// #enddocregion parent-to-child-setter
|
// #enddocregion parent-to-child-setter
|
||||||
|
@ -82,7 +82,7 @@ describe('Component Communication Cookbook Tests', function () {
|
||||||
expect(actual.label).toBe(labelAfter2Minor);
|
expect(actual.label).toBe(labelAfter2Minor);
|
||||||
expect(actual.count).toBe(3);
|
expect(actual.count).toBe(3);
|
||||||
expect(actual.logs.get(2).getText()).toBe(logAfter2Minor);
|
expect(actual.logs.get(2).getText()).toBe(logAfter2Minor);
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -150,13 +150,15 @@ describe('Component Communication Cookbook Tests', function () {
|
||||||
// ...
|
// ...
|
||||||
// #enddocregion child-to-parent
|
// #enddocregion child-to-parent
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Parent calls child via local var', function() {
|
// Can't run timer tests in protractor because
|
||||||
countDownTimerTests('countdown-parent-lv')
|
// interaction w/ zones causes all tests to freeze & timeout.
|
||||||
});
|
xdescribe('Parent calls child via local var', function() {
|
||||||
|
countDownTimerTests('countdown-parent-lv');
|
||||||
describe('Parent calls ViewChild', function() {
|
});
|
||||||
countDownTimerTests('countdown-parent-vc')
|
|
||||||
|
xdescribe('Parent calls ViewChild', function() {
|
||||||
|
countDownTimerTests('countdown-parent-vc');
|
||||||
});
|
});
|
||||||
|
|
||||||
function countDownTimerTests(parentTag: string) {
|
function countDownTimerTests(parentTag: string) {
|
||||||
|
@ -180,7 +182,7 @@ describe('Component Communication Cookbook Tests', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// ...
|
// ...
|
||||||
// #enddocregion countdown-timer-tests
|
// #enddocregion countdown-timer-tests
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,20 @@ import { MissionControlComponent } from './missioncontrol.component';
|
||||||
NameParentComponent,
|
NameParentComponent,
|
||||||
VersionParentComponent,
|
VersionParentComponent,
|
||||||
VoteTakerComponent,
|
VoteTakerComponent,
|
||||||
CountdownLocalVarParentComponent,
|
MissionControlComponent,
|
||||||
CountdownViewChildParentComponent,
|
];
|
||||||
MissionControlComponent
|
|
||||||
]
|
// Include Countdown examples
|
||||||
|
// unless in e2e tests which they break.
|
||||||
|
if (!/e2e/.test(location.search)) {
|
||||||
|
console.log('adding countdown timer examples');
|
||||||
|
directives.push(CountdownLocalVarParentComponent);
|
||||||
|
directives.push(CountdownViewChildParentComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app',
|
||||||
|
templateUrl: 'app/app.component.html',
|
||||||
|
directives: directives
|
||||||
})
|
})
|
||||||
export class AppComponent { }
|
export class AppComponent { }
|
||||||
|
|
|
@ -17,12 +17,12 @@ import { Subscription } from 'rxjs/Subscription';
|
||||||
</p>
|
</p>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
export class AstronautComponent implements OnDestroy{
|
export class AstronautComponent implements OnDestroy {
|
||||||
@Input() astronaut: string;
|
@Input() astronaut: string;
|
||||||
mission = "<no mission announced>";
|
mission = '<no mission announced>';
|
||||||
confirmed = false;
|
confirmed = false;
|
||||||
announced = false;
|
announced = false;
|
||||||
subscription:Subscription;
|
subscription: Subscription;
|
||||||
|
|
||||||
constructor(private missionService: MissionService) {
|
constructor(private missionService: MissionService) {
|
||||||
this.subscription = missionService.missionAnnounced$.subscribe(
|
this.subscription = missionService.missionAnnounced$.subscribe(
|
||||||
|
@ -30,7 +30,7 @@ export class AstronautComponent implements OnDestroy{
|
||||||
this.mission = mission;
|
this.mission = mission;
|
||||||
this.announced = true;
|
this.announced = true;
|
||||||
this.confirmed = false;
|
this.confirmed = false;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
confirm() {
|
confirm() {
|
||||||
|
@ -38,9 +38,9 @@ export class AstronautComponent implements OnDestroy{
|
||||||
this.missionService.confirmMission(this.astronaut);
|
this.missionService.confirmMission(this.astronaut);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(){
|
ngOnDestroy() {
|
||||||
// prevent memory leak when component destroyed
|
// prevent memory leak when component destroyed
|
||||||
this.subscription.unsubscribe();
|
this.subscription.unsubscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { CountdownTimerComponent } from './countdown-timer.component';
|
||||||
//// Local variable, #timer, version
|
//// Local variable, #timer, version
|
||||||
// #docregion lv
|
// #docregion lv
|
||||||
@Component({
|
@Component({
|
||||||
selector:'countdown-parent-lv',
|
selector: 'countdown-parent-lv',
|
||||||
template: `
|
template: `
|
||||||
<h3>Countdown to Liftoff (via local variable)</h3>
|
<h3>Countdown to Liftoff (via local variable)</h3>
|
||||||
<button (click)="timer.start()">Start</button>
|
<button (click)="timer.start()">Start</button>
|
||||||
|
@ -28,7 +28,7 @@ export class CountdownLocalVarParentComponent { }
|
||||||
//// View Child version
|
//// View Child version
|
||||||
// #docregion vc
|
// #docregion vc
|
||||||
@Component({
|
@Component({
|
||||||
selector:'countdown-parent-vc',
|
selector: 'countdown-parent-vc',
|
||||||
template: `
|
template: `
|
||||||
<h3>Countdown to Liftoff (via ViewChild)</h3>
|
<h3>Countdown to Liftoff (via ViewChild)</h3>
|
||||||
<button (click)="start()">Start</button>
|
<button (click)="start()">Start</button>
|
||||||
|
@ -42,7 +42,7 @@ export class CountdownLocalVarParentComponent { }
|
||||||
export class CountdownViewChildParentComponent implements AfterViewInit {
|
export class CountdownViewChildParentComponent implements AfterViewInit {
|
||||||
|
|
||||||
@ViewChild(CountdownTimerComponent)
|
@ViewChild(CountdownTimerComponent)
|
||||||
private timerComponent:CountdownTimerComponent;
|
private timerComponent: CountdownTimerComponent;
|
||||||
|
|
||||||
seconds() { return 0; }
|
seconds() { return 0; }
|
||||||
|
|
||||||
|
@ -50,10 +50,10 @@ export class CountdownViewChildParentComponent implements AfterViewInit {
|
||||||
// Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ...
|
// Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ...
|
||||||
// but wait a tick first to avoid one-time devMode
|
// but wait a tick first to avoid one-time devMode
|
||||||
// unidirectional-data-flow-violation error
|
// unidirectional-data-flow-violation error
|
||||||
setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0)
|
setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
start(){ this.timerComponent.start(); }
|
start() { this.timerComponent.start(); }
|
||||||
stop() { this.timerComponent.stop(); }
|
stop() { this.timerComponent.stop(); }
|
||||||
}
|
}
|
||||||
// #enddocregion vc
|
// #enddocregion vc
|
||||||
|
|
|
@ -11,7 +11,7 @@ export class CountdownTimerComponent implements OnInit, OnDestroy {
|
||||||
message = '';
|
message = '';
|
||||||
seconds = 11;
|
seconds = 11;
|
||||||
|
|
||||||
clearTimer() {clearInterval(this.intervalId);}
|
clearTimer() { clearInterval(this.intervalId); }
|
||||||
|
|
||||||
ngOnInit() { this.start(); }
|
ngOnInit() { this.start(); }
|
||||||
ngOnDestroy() { this.clearTimer(); }
|
ngOnDestroy() { this.clearTimer(); }
|
||||||
|
|
|
@ -6,4 +6,4 @@ export const HEROES = [
|
||||||
{name: 'Mr. IQ'},
|
{name: 'Mr. IQ'},
|
||||||
{name: 'Magneta'},
|
{name: 'Magneta'},
|
||||||
{name: 'Bombasto'}
|
{name: 'Bombasto'}
|
||||||
];
|
];
|
||||||
|
|
|
@ -2,4 +2,4 @@ import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
bootstrap(AppComponent);
|
bootstrap(AppComponent);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core';
|
||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -15,7 +15,7 @@ export class MissionService {
|
||||||
|
|
||||||
// Service message commands
|
// Service message commands
|
||||||
announceMission(mission: string) {
|
announceMission(mission: string) {
|
||||||
this.missionAnnouncedSource.next(mission)
|
this.missionAnnouncedSource.next(mission);
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmMission(astronaut: string) {
|
confirmMission(astronaut: string) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { MissionService } from './mission.service';
|
||||||
providers: [MissionService]
|
providers: [MissionService]
|
||||||
})
|
})
|
||||||
export class MissionControlComponent {
|
export class MissionControlComponent {
|
||||||
astronauts = ['Lovell', 'Swigert', 'Haise']
|
astronauts = ['Lovell', 'Swigert', 'Haise'];
|
||||||
history: string[] = [];
|
history: string[] = [];
|
||||||
missions = ['Fly to the moon!',
|
missions = ['Fly to the moon!',
|
||||||
'Fly to mars!',
|
'Fly to mars!',
|
||||||
|
@ -32,7 +32,7 @@ export class MissionControlComponent {
|
||||||
missionService.missionConfirmed$.subscribe(
|
missionService.missionConfirmed$.subscribe(
|
||||||
astronaut => {
|
astronaut => {
|
||||||
this.history.push(`${astronaut} confirmed the mission`);
|
this.history.push(`${astronaut} confirmed the mission`);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
announce() {
|
announce() {
|
||||||
|
|
|
@ -17,7 +17,7 @@ export class VersionChildComponent implements OnChanges {
|
||||||
@Input() minor: number;
|
@Input() minor: number;
|
||||||
changeLog: string[] = [];
|
changeLog: string[] = [];
|
||||||
|
|
||||||
ngOnChanges(changes: {[propKey:string]: SimpleChange}){
|
ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
|
||||||
let log: string[] = [];
|
let log: string[] = [];
|
||||||
for (let propName in changes) {
|
for (let propName in changes) {
|
||||||
let changedProp = changes[propName];
|
let changedProp = changes[propName];
|
||||||
|
|
|
@ -14,9 +14,9 @@ export class VoterComponent {
|
||||||
@Output() onVoted = new EventEmitter<boolean>();
|
@Output() onVoted = new EventEmitter<boolean>();
|
||||||
voted = false;
|
voted = false;
|
||||||
|
|
||||||
vote(agreed:boolean){
|
vote(agreed: boolean) {
|
||||||
this.onVoted.emit(agreed);
|
this.onVoted.emit(agreed);
|
||||||
this.voted = true;
|
this.voted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { VoterComponent } from './voter.component';
|
||||||
export class VoteTakerComponent {
|
export class VoteTakerComponent {
|
||||||
agreed = 0;
|
agreed = 0;
|
||||||
disagreed = 0;
|
disagreed = 0;
|
||||||
voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto']
|
voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto'];
|
||||||
|
|
||||||
onVoted(agreed: boolean) {
|
onVoted(agreed: boolean) {
|
||||||
agreed ? this.agreed++ : this.disagreed++;
|
agreed ? this.agreed++ : this.disagreed++;
|
||||||
|
|
|
@ -12,7 +12,7 @@ describe('Cookbook: component-relative paths', function () {
|
||||||
title: element( by.tagName( 'h1' )),
|
title: element( by.tagName( 'h1' )),
|
||||||
absComp: element( by.css( 'absolute-path div' ) ),
|
absComp: element( by.css( 'absolute-path div' ) ),
|
||||||
relComp: element( by.css( 'relative-path div' ) )
|
relComp: element( by.css( 'relative-path div' ) )
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let page: Page;
|
let page: Page;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { SomeAbsoluteComponent, SomeRelativeComponent} from './some.component';
|
import { SomeAbsoluteComponent, SomeRelativeComponent } from './some.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-app',
|
selector: 'my-app',
|
||||||
|
|
|
@ -66,7 +66,7 @@ describe('Dependency Injection Cookbook', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should highlight Hero Bios and Contacts container when mouseover', function () {
|
it('should highlight Hero Bios and Contacts container when mouseover', function () {
|
||||||
let target = element(by.css('div[myHighlight="yellow"]'))
|
let target = element(by.css('div[myHighlight="yellow"]'));
|
||||||
let yellow = 'rgba(255, 255, 0, 1)';
|
let yellow = 'rgba(255, 255, 0, 1)';
|
||||||
|
|
||||||
expect(target.getCssValue('background-color')).not.toEqual(yellow);
|
expect(target.getCssValue('background-color')).not.toEqual(yellow);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { HeroBiosComponent,
|
import { HeroBiosComponent,
|
||||||
HeroBiosAndContactsComponent} from './hero-bios.component';
|
HeroBiosAndContactsComponent } from './hero-bios.component';
|
||||||
import { HeroOfTheMonthComponent } from './hero-of-the-month.component';
|
import { HeroOfTheMonthComponent } from './hero-of-the-month.component';
|
||||||
import { HeroesBaseComponent,
|
import { HeroesBaseComponent,
|
||||||
SortedHeroesComponent } from './sorted-heroes.component';
|
SortedHeroesComponent } from './sorted-heroes.component';
|
||||||
|
|
|
@ -6,9 +6,9 @@ import { HeroCacheService } from './hero-cache.service';
|
||||||
|
|
||||||
// #docregion component
|
// #docregion component
|
||||||
@Component({
|
@Component({
|
||||||
selector:'hero-bio',
|
selector: 'hero-bio',
|
||||||
// #docregion template
|
// #docregion template
|
||||||
template:`
|
template: `
|
||||||
<h4>{{hero.name}}</h4>
|
<h4>{{hero.name}}</h4>
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
<textarea cols="25" [(ngModel)]="hero.description"></textarea>`,
|
<textarea cols="25" [(ngModel)]="hero.description"></textarea>`,
|
||||||
|
@ -18,9 +18,9 @@ import { HeroCacheService } from './hero-cache.service';
|
||||||
|
|
||||||
export class HeroBioComponent implements OnInit {
|
export class HeroBioComponent implements OnInit {
|
||||||
|
|
||||||
@Input() heroId:number;
|
@Input() heroId: number;
|
||||||
|
|
||||||
constructor(private heroCache:HeroCacheService) { }
|
constructor(private heroCache: HeroCacheService) { }
|
||||||
|
|
||||||
ngOnInit() { this.heroCache.fetchCachedHero(this.heroId); }
|
ngOnInit() { this.heroCache.fetchCachedHero(this.heroId); }
|
||||||
|
|
||||||
|
|
|
@ -10,15 +10,15 @@ import { LoggerService } from './logger.service';
|
||||||
//////// HeroBiosComponent ////
|
//////// HeroBiosComponent ////
|
||||||
// #docregion simple
|
// #docregion simple
|
||||||
@Component({
|
@Component({
|
||||||
selector:'hero-bios',
|
selector: 'hero-bios',
|
||||||
template:`
|
template: `
|
||||||
<hero-bio [heroId]="1"></hero-bio>
|
<hero-bio [heroId]="1"></hero-bio>
|
||||||
<hero-bio [heroId]="2"></hero-bio>
|
<hero-bio [heroId]="2"></hero-bio>
|
||||||
<hero-bio [heroId]="3"></hero-bio>`,
|
<hero-bio [heroId]="3"></hero-bio>`,
|
||||||
directives:[HeroBioComponent],
|
directives: [HeroBioComponent],
|
||||||
providers: [HeroService]
|
providers: [HeroService]
|
||||||
})
|
})
|
||||||
export class HeroBiosComponent{
|
export class HeroBiosComponent {
|
||||||
// #enddocregion simple
|
// #enddocregion simple
|
||||||
// #docregion ctor
|
// #docregion ctor
|
||||||
constructor(logger: LoggerService) {
|
constructor(logger: LoggerService) {
|
||||||
|
@ -32,21 +32,21 @@ export class HeroBiosComponent{
|
||||||
//////// HeroBiosAndContactsComponent ////
|
//////// HeroBiosAndContactsComponent ////
|
||||||
// #docregion hero-bios-and-contacts
|
// #docregion hero-bios-and-contacts
|
||||||
@Component({
|
@Component({
|
||||||
selector:'hero-bios-and-contacts',
|
selector: 'hero-bios-and-contacts',
|
||||||
// #docregion template
|
// #docregion template
|
||||||
template:`
|
template: `
|
||||||
<hero-bio [heroId]="1"> <hero-contact></hero-contact> </hero-bio>
|
<hero-bio [heroId]="1"> <hero-contact></hero-contact> </hero-bio>
|
||||||
<hero-bio [heroId]="2"> <hero-contact></hero-contact> </hero-bio>
|
<hero-bio [heroId]="2"> <hero-contact></hero-contact> </hero-bio>
|
||||||
<hero-bio [heroId]="3"> <hero-contact></hero-contact> </hero-bio>`,
|
<hero-bio [heroId]="3"> <hero-contact></hero-contact> </hero-bio>`,
|
||||||
// #enddocregion template
|
// #enddocregion template
|
||||||
directives:[HeroBioComponent, HeroContactComponent],
|
directives: [HeroBioComponent, HeroContactComponent],
|
||||||
// #docregion class-provider
|
// #docregion class-provider
|
||||||
providers: [HeroService]
|
providers: [HeroService]
|
||||||
// #enddocregion class-provider
|
// #enddocregion class-provider
|
||||||
})
|
})
|
||||||
export class HeroBiosAndContactsComponent{
|
export class HeroBiosAndContactsComponent {
|
||||||
constructor(logger: LoggerService) {
|
constructor(logger: LoggerService) {
|
||||||
logger.logInfo('Creating HeroBiosAndContactsComponent');
|
logger.logInfo('Creating HeroBiosAndContactsComponent');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #enddocregion hero-bios-and-contacts
|
// #enddocregion hero-bios-and-contacts
|
||||||
|
|
|
@ -7,14 +7,14 @@ import { HeroService } from './hero.service';
|
||||||
// #docregion service
|
// #docregion service
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class HeroCacheService {
|
export class HeroCacheService {
|
||||||
hero:Hero;
|
hero: Hero;
|
||||||
constructor(private heroService:HeroService){}
|
constructor(private heroService: HeroService) {}
|
||||||
|
|
||||||
fetchCachedHero(id:number){
|
fetchCachedHero(id: number) {
|
||||||
if (!this.hero) {
|
if (!this.hero) {
|
||||||
this.hero = this.heroService.getHeroById(id);
|
this.hero = this.heroService.getHeroById(id);
|
||||||
}
|
}
|
||||||
return this.hero
|
return this.hero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #enddocregion service
|
// #enddocregion service
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component, ElementRef, Host, Inject, Optional } from '@angular/core';
|
import { Component, ElementRef, Host, Inject, Optional } from '@angular/core';
|
||||||
|
|
||||||
import { HeroCacheService } from './hero-cache.service';
|
import { HeroCacheService } from './hero-cache.service';
|
||||||
import { LoggerService } from './logger.service';
|
import { LoggerService } from './logger.service';
|
||||||
|
|
||||||
// #docregion component
|
// #docregion component
|
||||||
@Component({
|
@Component({
|
||||||
selector:'hero-contact',
|
selector: 'hero-contact',
|
||||||
template:`
|
template: `
|
||||||
<div>Phone #: {{phoneNumber}}
|
<div>Phone #: {{phoneNumber}}
|
||||||
<span *ngIf="hasLogger">!!!</span></div>`
|
<span *ngIf="hasLogger">!!!</span></div>`
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,10 +4,10 @@ import { Hero } from './hero';
|
||||||
export class HeroData {
|
export class HeroData {
|
||||||
createDb() {
|
createDb() {
|
||||||
let heroes = [
|
let heroes = [
|
||||||
new Hero(1,"Windstorm"),
|
new Hero(1, 'Windstorm'),
|
||||||
new Hero(2,"Bombasto"),
|
new Hero(2, 'Bombasto'),
|
||||||
new Hero(3,"Magneta"),
|
new Hero(3, 'Magneta'),
|
||||||
new Hero(4,"Tornado")
|
new Hero(4, 'Tornado')
|
||||||
];
|
];
|
||||||
return {heroes};
|
return {heroes};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,18 +5,18 @@ import { Hero } from './hero';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class HeroService {
|
export class HeroService {
|
||||||
|
|
||||||
//TODO move to database
|
// TODO move to database
|
||||||
private heroes:Array<Hero> = [
|
private heroes: Array<Hero> = [
|
||||||
new Hero(1, 'RubberMan','Hero of many talents', '123-456-7899'),
|
new Hero(1, 'RubberMan', 'Hero of many talents', '123-456-7899'),
|
||||||
new Hero(2, 'Magma','Hero of all trades', '555-555-5555'),
|
new Hero(2, 'Magma', 'Hero of all trades', '555-555-5555'),
|
||||||
new Hero(3, 'Mr. Nice','The name says it all','111-222-3333')
|
new Hero(3, 'Mr. Nice', 'The name says it all', '111-222-3333')
|
||||||
];
|
];
|
||||||
|
|
||||||
getHeroById(id:number):Hero{
|
getHeroById(id: number): Hero {
|
||||||
return this.heroes.filter(hero => hero.id === id)[0];
|
return this.heroes.filter(hero => hero.id === id)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllHeroes():Array<Hero>{
|
getAllHeroes(): Array<Hero> {
|
||||||
return this.heroes;
|
return this.heroes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
export class Hero{
|
export class Hero {
|
||||||
constructor(
|
constructor(
|
||||||
public id: number,
|
public id: number,
|
||||||
public name:string,
|
public name: string,
|
||||||
public description?:string,
|
public description?: string,
|
||||||
public phone?:string) {
|
public phone?: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ const provideParent =
|
||||||
// #enddocregion provide-parent, provide-the-parent
|
// #enddocregion provide-parent, provide-the-parent
|
||||||
// #docregion provide-parent
|
// #docregion provide-parent
|
||||||
(component: any, parentType?: any) => {
|
(component: any, parentType?: any) => {
|
||||||
return { provide: parentType || Parent, useExisting: forwardRef(() => component) }
|
return { provide: parentType || Parent, useExisting: forwardRef(() => component) };
|
||||||
};
|
};
|
||||||
// #enddocregion provide-parent
|
// #enddocregion provide-parent
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ const provideParent =
|
||||||
const provideTheParent =
|
const provideTheParent =
|
||||||
// #docregion provide-the-parent
|
// #docregion provide-the-parent
|
||||||
(component: any) => {
|
(component: any) => {
|
||||||
return { provide: Parent, useExisting: forwardRef(() => component) }
|
return { provide: Parent, useExisting: forwardRef(() => component) };
|
||||||
};
|
};
|
||||||
// #enddocregion provide-the-parent
|
// #enddocregion provide-the-parent
|
||||||
|
|
||||||
|
|
|
@ -9,19 +9,19 @@ import { UserService } from './user.service';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserContextService {
|
export class UserContextService {
|
||||||
// #enddocregion injectables, injectable
|
// #enddocregion injectables, injectable
|
||||||
name:string;
|
name: string;
|
||||||
role:string;
|
role: string;
|
||||||
loggedInSince:Date;
|
loggedInSince: Date;
|
||||||
|
|
||||||
// #docregion ctor, injectables
|
// #docregion ctor, injectables
|
||||||
constructor(private userService:UserService, private loggerService:LoggerService){
|
constructor(private userService: UserService, private loggerService: LoggerService) {
|
||||||
// #enddocregion ctor, injectables
|
// #enddocregion ctor, injectables
|
||||||
this.loggedInSince = new Date();
|
this.loggedInSince = new Date();
|
||||||
// #docregion ctor, injectables
|
// #docregion ctor, injectables
|
||||||
}
|
}
|
||||||
// #enddocregion ctor, injectables
|
// #enddocregion ctor, injectables
|
||||||
|
|
||||||
loadUser(userId:number){
|
loadUser(userId: number) {
|
||||||
let user = this.userService.getUserById(userId);
|
let user = this.userService.getUserById(userId);
|
||||||
this.name = user.name;
|
this.name = user.name;
|
||||||
this.role = user.role;
|
this.role = user.role;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Injectable } from '@angular/core';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
|
|
||||||
getUserById(userId:number):any{
|
getUserById(userId: number): any {
|
||||||
return {name:'Bombasto',role:'Admin'};
|
return {name: 'Bombasto', role: 'Admin'};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ describe('Dynamic Form', function () {
|
||||||
emailElement.sendKeys(email);
|
emailElement.sendKeys(email);
|
||||||
expect(emailElement.getAttribute('value')).toEqual(email);
|
expect(emailElement.getAttribute('value')).toEqual(email);
|
||||||
|
|
||||||
element(by.css('select option[value="solid"]')).click()
|
element(by.css('select option[value="solid"]')).click();
|
||||||
|
|
||||||
let saveButton = element.all(by.css('button')).get(0);
|
let saveButton = element.all(by.css('button')).get(0);
|
||||||
saveButton.click().then(function(){
|
saveButton.click().then(function(){
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component } from '@angular/core'
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { DynamicForm } from './dynamic-form.component';
|
import { DynamicForm } from './dynamic-form.component';
|
||||||
import { QuestionService } from './question.service';
|
import { QuestionService } from './question.service';
|
||||||
|
@ -16,7 +16,7 @@ import { QuestionService } from './question.service';
|
||||||
providers: [QuestionService]
|
providers: [QuestionService]
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
questions:any[]
|
questions: any[];
|
||||||
|
|
||||||
constructor(service: QuestionService) {
|
constructor(service: QuestionService) {
|
||||||
this.questions = service.getQuestions();
|
this.questions = service.getQuestions();
|
||||||
|
|
|
@ -5,11 +5,11 @@ import { ControlGroup } from '@angular/common';
|
||||||
import { QuestionBase } from './question-base';
|
import { QuestionBase } from './question-base';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector:'df-question',
|
selector: 'df-question',
|
||||||
templateUrl:'app/dynamic-form-question.component.html'
|
templateUrl: 'app/dynamic-form-question.component.html'
|
||||||
})
|
})
|
||||||
export class DynamicFormQuestionComponent {
|
export class DynamicFormQuestionComponent {
|
||||||
@Input() question:QuestionBase<any>;
|
@Input() question: QuestionBase<any>;
|
||||||
@Input() form:ControlGroup;
|
@Input() form: ControlGroup;
|
||||||
get isValid() { return this.form.controls[this.question.key].valid; }
|
get isValid() { return this.form.controls[this.question.key].valid; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ import { QuestionControlService } from './question-control.service';
|
||||||
import { DynamicFormQuestionComponent } from './dynamic-form-question.component';
|
import { DynamicFormQuestionComponent } from './dynamic-form-question.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector:'dynamic-form',
|
selector: 'dynamic-form',
|
||||||
templateUrl:'app/dynamic-form.component.html',
|
templateUrl: 'app/dynamic-form.component.html',
|
||||||
directives: [DynamicFormQuestionComponent],
|
directives: [DynamicFormQuestionComponent],
|
||||||
providers: [QuestionControlService]
|
providers: [QuestionControlService]
|
||||||
})
|
})
|
||||||
|
@ -20,7 +20,7 @@ export class DynamicForm {
|
||||||
|
|
||||||
constructor(private qcs: QuestionControlService) { }
|
constructor(private qcs: QuestionControlService) { }
|
||||||
|
|
||||||
ngOnInit(){
|
ngOnInit() {
|
||||||
this.form = this.qcs.toControlGroup(this.questions);
|
this.form = this.qcs.toControlGroup(this.questions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,4 +3,4 @@ import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
bootstrap(AppComponent, [])
|
bootstrap(AppComponent, [])
|
||||||
.catch((err:any) => console.error(err));
|
.catch((err: any) => console.error(err));
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
export class QuestionBase<T>{
|
export class QuestionBase<T>{
|
||||||
value:T;
|
value: T;
|
||||||
key:string;
|
key: string;
|
||||||
label:string;
|
label: string;
|
||||||
required:boolean;
|
required: boolean;
|
||||||
order:number;
|
order: number;
|
||||||
controlType:string;
|
controlType: string;
|
||||||
|
|
||||||
constructor(options:{
|
constructor(options: {
|
||||||
value?:T,
|
value?: T,
|
||||||
key?:string,
|
key?: string,
|
||||||
label?:string,
|
label?: string,
|
||||||
required?:boolean,
|
required?: boolean,
|
||||||
order?:number,
|
order?: number,
|
||||||
controlType?:string
|
controlType?: string
|
||||||
} = {}){
|
} = {}) {
|
||||||
this.value = options.value;
|
this.value = options.value;
|
||||||
this.key = options.key || '';
|
this.key = options.key || '';
|
||||||
this.label = options.label || '';
|
this.label = options.label || '';
|
||||||
|
|
|
@ -5,9 +5,9 @@ import { QuestionBase } from './question-base';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QuestionControlService {
|
export class QuestionControlService {
|
||||||
constructor(private fb:FormBuilder){ }
|
constructor(private fb: FormBuilder) { }
|
||||||
|
|
||||||
toControlGroup(questions:QuestionBase<any>[] ) {
|
toControlGroup(questions: QuestionBase<any>[] ) {
|
||||||
let group = {};
|
let group = {};
|
||||||
|
|
||||||
questions.forEach(question => {
|
questions.forEach(question => {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import { QuestionBase } from './question-base';
|
import { QuestionBase } from './question-base';
|
||||||
|
|
||||||
export class DropdownQuestion extends QuestionBase<string>{
|
export class DropdownQuestion extends QuestionBase<string> {
|
||||||
controlType = 'dropdown';
|
controlType = 'dropdown';
|
||||||
options:{key:string, value:string}[] = [];
|
options: {key: string, value: string}[] = [];
|
||||||
|
|
||||||
constructor(options:{} = {}){
|
constructor(options: {} = {}) {
|
||||||
super(options);
|
super(options);
|
||||||
this.options = options['options'] || [];
|
this.options = options['options'] || [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import { QuestionBase } from './question-base';
|
import { QuestionBase } from './question-base';
|
||||||
|
|
||||||
export class TextboxQuestion extends QuestionBase<string>{
|
export class TextboxQuestion extends QuestionBase<string> {
|
||||||
controlType = 'textbox';
|
controlType = 'textbox';
|
||||||
type:string;
|
type: string;
|
||||||
|
|
||||||
constructor(options:{} = {}){
|
constructor(options: {} = {}) {
|
||||||
super(options);
|
super(options);
|
||||||
this.type = options['type'] || '';
|
this.type = options['type'] || '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,36 +13,36 @@ export class QuestionService {
|
||||||
// Todo: make asynchronous
|
// Todo: make asynchronous
|
||||||
getQuestions() {
|
getQuestions() {
|
||||||
|
|
||||||
let questions:QuestionBase<any>[] = [
|
let questions: QuestionBase<any>[] = [
|
||||||
|
|
||||||
new DropdownQuestion({
|
new DropdownQuestion({
|
||||||
key:'brave',
|
key: 'brave',
|
||||||
label: 'Bravery Rating',
|
label: 'Bravery Rating',
|
||||||
options: [
|
options: [
|
||||||
{key:'solid', value:'Solid'},
|
{key: 'solid', value: 'Solid'},
|
||||||
{key:'great', value:'Great'},
|
{key: 'great', value: 'Great'},
|
||||||
{key:'good', value:'Good'},
|
{key: 'good', value: 'Good'},
|
||||||
{key:'unproven',value:'Unproven'}
|
{key: 'unproven', value: 'Unproven'}
|
||||||
],
|
],
|
||||||
order: 3
|
order: 3
|
||||||
}),
|
}),
|
||||||
|
|
||||||
new TextboxQuestion({
|
new TextboxQuestion({
|
||||||
key:'firstName',
|
key: 'firstName',
|
||||||
label:'First name',
|
label: 'First name',
|
||||||
value:'Bombasto',
|
value: 'Bombasto',
|
||||||
required: true,
|
required: true,
|
||||||
order: 1
|
order: 1
|
||||||
}),
|
}),
|
||||||
|
|
||||||
new TextboxQuestion({
|
new TextboxQuestion({
|
||||||
key:'emailAddress',
|
key: 'emailAddress',
|
||||||
label:'Email',
|
label: 'Email',
|
||||||
type: 'email',
|
type: 'email',
|
||||||
order: 2
|
order: 2
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
return questions.sort((a,b) => a.order - b.order);
|
return questions.sort((a, b) => a.order - b.order);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* tslint:disable */
|
||||||
// #docregion
|
// #docregion
|
||||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,11 @@ export class TitleComponent {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject('titlePrefix')
|
@Inject('titlePrefix')
|
||||||
@Optional()
|
@Optional()
|
||||||
private titlePrefix:string,
|
private titlePrefix: string,
|
||||||
@Attribute('title')
|
@Attribute('title')
|
||||||
private title:string,
|
private title: string,
|
||||||
@Query('okMsg')
|
@Query('okMsg')
|
||||||
private msg:QueryList<ElementRef>) {
|
private msg: QueryList<ElementRef>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ok() {
|
ok() {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { Component, Inject } from '@angular/core';
|
||||||
export class HeroComponent {
|
export class HeroComponent {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject('heroName')
|
@Inject('heroName')
|
||||||
private name:string) {
|
private name: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
|
|
@ -8,8 +8,8 @@ import { DataService } from './data.service';
|
||||||
template: `<h1>Hero: {{name}}</h1>`
|
template: `<h1>Hero: {{name}}</h1>`
|
||||||
})
|
})
|
||||||
export class HeroComponent {
|
export class HeroComponent {
|
||||||
name:string;
|
name: string;
|
||||||
constructor(dataService:DataService) {
|
constructor(dataService: DataService) {
|
||||||
this.name = dataService.getHeroName();
|
this.name = dataService.getHeroName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,8 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
export class ConfirmComponent {
|
export class ConfirmComponent {
|
||||||
@Input() okMsg:string;
|
@Input() okMsg: string;
|
||||||
@Input('cancelMsg') notOkMsg:string;
|
@Input('cancelMsg') notOkMsg: string;
|
||||||
@Output() ok =
|
@Output() ok =
|
||||||
new EventEmitter();
|
new EventEmitter();
|
||||||
@Output('cancel') notOk =
|
@Output('cancel') notOk =
|
||||||
|
@ -44,8 +44,8 @@ export class ConfirmComponent {
|
||||||
directives: [ConfirmComponent]
|
directives: [ConfirmComponent]
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
okClicked:boolean;
|
okClicked: boolean;
|
||||||
cancelClicked:boolean;
|
cancelClicked: boolean;
|
||||||
|
|
||||||
onOk() {
|
onOk() {
|
||||||
this.okClicked = true;
|
this.okClicked = true;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { Component, OnInit }
|
||||||
// #docregion
|
// #docregion
|
||||||
export class HeroComponent
|
export class HeroComponent
|
||||||
implements OnInit {
|
implements OnInit {
|
||||||
name:string;
|
name: string;
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.name = 'Windstorm';
|
this.name = 'Windstorm';
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,14 @@ import { Component } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hero-view',
|
selector: 'hero-view',
|
||||||
template:
|
template:
|
||||||
'<h1>Hero: {{getName()}}</h1>'
|
'<h1>Hero: {{getName()}}</h1>'
|
||||||
})
|
})
|
||||||
// #docregion appexport
|
// #docregion appexport
|
||||||
// #docregion class
|
// #docregion class
|
||||||
export class HeroComponent {
|
export class HeroComponent {
|
||||||
title = 'Hero Detail';
|
title = 'Hero Detail';
|
||||||
getName() {return 'Windstorm';}
|
getName() {return 'Windstorm'; }
|
||||||
}
|
}
|
||||||
// #enddocregion class
|
// #enddocregion class
|
||||||
// #enddocregion appexport
|
// #enddocregion appexport
|
||||||
|
|
|
@ -10,8 +10,8 @@ import { Component, HostBinding, HostListener } from '@angular/core';
|
||||||
export class HeroesComponent {
|
export class HeroesComponent {
|
||||||
@HostBinding() title = 'Tooltip content';
|
@HostBinding() title = 'Tooltip content';
|
||||||
@HostBinding('class.heading')
|
@HostBinding('class.heading')
|
||||||
hClass = true
|
hClass = true;
|
||||||
active:boolean;
|
active: boolean;
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ export class HeroesComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('dblclick', ['$event'])
|
@HostListener('dblclick', ['$event'])
|
||||||
doubleClicked(evt:Event) {
|
doubleClicked(evt: Event) {
|
||||||
this.active = true;
|
this.active = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {
|
||||||
</span>`
|
</span>`
|
||||||
})
|
})
|
||||||
class ActiveLabelComponent {
|
class ActiveLabelComponent {
|
||||||
active:boolean;
|
active: boolean;
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
this.active = true;
|
this.active = true;
|
||||||
|
@ -30,11 +30,11 @@ class ActiveLabelComponent {
|
||||||
</h2>`
|
</h2>`
|
||||||
})
|
})
|
||||||
class HeroComponent {
|
class HeroComponent {
|
||||||
@Input() hero:any;
|
@Input() hero: any;
|
||||||
active:boolean;
|
active: boolean;
|
||||||
|
|
||||||
@ContentChild(ActiveLabelComponent)
|
@ContentChild(ActiveLabelComponent)
|
||||||
label:ActiveLabelComponent
|
label: ActiveLabelComponent;
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
this.active = true;
|
this.active = true;
|
||||||
|
@ -68,7 +68,7 @@ export class HeroesQueriesComponent {
|
||||||
];
|
];
|
||||||
|
|
||||||
@ViewChildren(HeroComponent)
|
@ViewChildren(HeroComponent)
|
||||||
heroCmps:QueryList<HeroComponent>;
|
heroCmps: QueryList<HeroComponent>;
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
this.heroCmps.forEach(
|
this.heroCmps.forEach(
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// #docregion ng2import
|
// #docregion ng2import
|
||||||
import { bootstrap }
|
import { bootstrap }
|
||||||
from '@angular/platform-browser-dynamic';
|
from '@angular/platform-browser-dynamic';
|
||||||
import {
|
|
||||||
} from '@angular/router';
|
|
||||||
import {
|
import {
|
||||||
LocationStrategy,
|
LocationStrategy,
|
||||||
HashLocationStrategy
|
HashLocationStrategy
|
||||||
|
|
|
@ -16,7 +16,7 @@ export class HeroAppComponent {
|
||||||
hero = new Hero(
|
hero = new Hero(
|
||||||
'Human Torch',
|
'Human Torch',
|
||||||
['Mister Fantastic', 'Invisible Woman', 'Thing']
|
['Mister Fantastic', 'Invisible Woman', 'Thing']
|
||||||
)
|
);
|
||||||
|
|
||||||
@HostBinding('class') get themeClass() {
|
@HostBinding('class') get themeClass() {
|
||||||
return 'theme-light';
|
return 'theme-light';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export class Hero {
|
export class Hero {
|
||||||
active:boolean;
|
active: boolean;
|
||||||
|
|
||||||
constructor(public name:string,
|
constructor(public name: string,
|
||||||
public team:string[]) {
|
public team: string[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ describe('Dependency Injection Tests', function () {
|
||||||
it('P10 (optional dependency) displays as expected', function () {
|
it('P10 (optional dependency) displays as expected', function () {
|
||||||
expectedMsg = 'Optional logger was not available';
|
expectedMsg = 'Optional logger was not available';
|
||||||
expect(element(by.css('#p10')).getText()).toEqual(expectedMsg);
|
expect(element(by.css('#p10')).getText()).toEqual(expectedMsg);
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('User/Heroes:', function() {
|
describe('User/Heroes:', function() {
|
||||||
|
@ -163,8 +163,8 @@ describe('Dependency Injection Tests', function () {
|
||||||
describe('after button click', function() {
|
describe('after button click', function() {
|
||||||
|
|
||||||
beforeAll(function (done) {
|
beforeAll(function (done) {
|
||||||
let buttonEle = element.all(by.cssContainingText('button','Next User')).get(0);
|
let buttonEle = element.all(by.cssContainingText('button', 'Next User')).get(0);
|
||||||
buttonEle.click().then(done,done);
|
buttonEle.click().then(done, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User is Alice - authorized', function () {
|
it('User is Alice - authorized', function () {
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { HeroesComponent } from './heroes/heroes.component.1';
|
||||||
<my-car></my-car>
|
<my-car></my-car>
|
||||||
<my-heroes></my-heroes>
|
<my-heroes></my-heroes>
|
||||||
`,
|
`,
|
||||||
directives:[CarComponent, HeroesComponent]
|
directives: [CarComponent, HeroesComponent]
|
||||||
})
|
})
|
||||||
|
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { Logger } from './logger.service';
|
||||||
<my-car></my-car>
|
<my-car></my-car>
|
||||||
<my-heroes></my-heroes>
|
<my-heroes></my-heroes>
|
||||||
`,
|
`,
|
||||||
directives:[CarComponent, HeroesComponent],
|
directives: [CarComponent, HeroesComponent],
|
||||||
providers: [
|
providers: [
|
||||||
Logger,
|
Logger,
|
||||||
// #docregion providers
|
// #docregion providers
|
||||||
|
@ -26,10 +26,10 @@ import { Logger } from './logger.service';
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title:string;
|
title: string;
|
||||||
|
|
||||||
// #docregion ctor
|
// #docregion ctor
|
||||||
constructor(@Inject(APP_CONFIG) config:AppConfig) {
|
constructor(@Inject(APP_CONFIG) config: AppConfig) {
|
||||||
this.title = config.title;
|
this.title = config.title;
|
||||||
}
|
}
|
||||||
// #enddocregion ctor
|
// #enddocregion ctor
|
||||||
|
|
|
@ -31,7 +31,7 @@ import { ProvidersComponent } from './providers.component';
|
||||||
<my-heroes id="authorized" *ngIf="isAuthorized"></my-heroes>
|
<my-heroes id="authorized" *ngIf="isAuthorized"></my-heroes>
|
||||||
<my-heroes id="unauthorized" *ngIf="!isAuthorized"></my-heroes>
|
<my-heroes id="unauthorized" *ngIf="!isAuthorized"></my-heroes>
|
||||||
`,
|
`,
|
||||||
directives:[CarComponent, HeroesComponent,
|
directives: [CarComponent, HeroesComponent,
|
||||||
InjectorComponent, TestComponent, ProvidersComponent],
|
InjectorComponent, TestComponent, ProvidersComponent],
|
||||||
// #docregion providers
|
// #docregion providers
|
||||||
providers: [
|
providers: [
|
||||||
|
@ -42,22 +42,22 @@ import { ProvidersComponent } from './providers.component';
|
||||||
// #enddocregion providers
|
// #enddocregion providers
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title:string;
|
title: string;
|
||||||
|
|
||||||
// #docregion ctor
|
// #docregion ctor
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(APP_CONFIG) config:AppConfig,
|
@Inject(APP_CONFIG) config: AppConfig,
|
||||||
private userService: UserService) {
|
private userService: UserService) {
|
||||||
this.title = config.title;
|
this.title = config.title;
|
||||||
}
|
}
|
||||||
// #enddocregion ctor
|
// #enddocregion ctor
|
||||||
|
|
||||||
get isAuthorized() { return this.user.isAuthorized;}
|
get isAuthorized() { return this.user.isAuthorized; }
|
||||||
nextUser() { this.userService.getNewUser(); }
|
nextUser() { this.userService.getNewUser(); }
|
||||||
get user() { return this.userService.user; }
|
get user() { return this.userService.user; }
|
||||||
|
|
||||||
get userInfo() {
|
get userInfo() {
|
||||||
return `Current user, ${this.user.name}, is `+
|
return `Current user, ${this.user.name}, is ` +
|
||||||
`${this.isAuthorized ? '' : 'not'} authorized. `;
|
`${this.isAuthorized ? '' : 'not'} authorized. `;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@ import { OpaqueToken } from '@angular/core';
|
||||||
export let APP_CONFIG = new OpaqueToken('app.config');
|
export let APP_CONFIG = new OpaqueToken('app.config');
|
||||||
// #enddocregion token
|
// #enddocregion token
|
||||||
|
|
||||||
//#docregion config
|
// #docregion config
|
||||||
export interface AppConfig {
|
export interface AppConfig {
|
||||||
apiEndpoint: string,
|
apiEndpoint: string;
|
||||||
title: string
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const HERO_DI_CONFIG: AppConfig = {
|
export const HERO_DI_CONFIG: AppConfig = {
|
||||||
|
|
|
@ -5,42 +5,42 @@ import { Car, Engine, Tires } from './car';
|
||||||
|
|
||||||
///////// example 1 ////////////
|
///////// example 1 ////////////
|
||||||
export function simpleCar() {
|
export function simpleCar() {
|
||||||
//#docregion car-ctor-instantiation
|
// #docregion car-ctor-instantiation
|
||||||
// Simple car with 4 cylinders and Flintstone tires.
|
// Simple car with 4 cylinders and Flintstone tires.
|
||||||
var car = new Car(new Engine(), new Tires());
|
let car = new Car(new Engine(), new Tires());
|
||||||
//#enddocregion car-ctor-instantiation
|
// #enddocregion car-ctor-instantiation
|
||||||
car.description = 'Simple';
|
car.description = 'Simple';
|
||||||
return car;
|
return car;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////// example 2 ////////////
|
///////// example 2 ////////////
|
||||||
//#docregion car-ctor-instantiation-with-param
|
// #docregion car-ctor-instantiation-with-param
|
||||||
class Engine2 {
|
class Engine2 {
|
||||||
constructor(public cylinders: number) { }
|
constructor(public cylinders: number) { }
|
||||||
}
|
}
|
||||||
//#enddocregion car-ctor-instantiation-with-param
|
// #enddocregion car-ctor-instantiation-with-param
|
||||||
export function superCar() {
|
export function superCar() {
|
||||||
//#docregion car-ctor-instantiation-with-param
|
// #docregion car-ctor-instantiation-with-param
|
||||||
// Super car with 12 cylinders and Flintstone tires.
|
// Super car with 12 cylinders and Flintstone tires.
|
||||||
var bigCylinders = 12;
|
let bigCylinders = 12;
|
||||||
var car = new Car(new Engine2(bigCylinders), new Tires());
|
let car = new Car(new Engine2(bigCylinders), new Tires());
|
||||||
//#enddocregion car-ctor-instantiation-with-param
|
// #enddocregion car-ctor-instantiation-with-param
|
||||||
car.description = 'Super';
|
car.description = 'Super';
|
||||||
return car;
|
return car;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////// example 3 //////////
|
/////////// example 3 //////////
|
||||||
//#docregion car-ctor-instantiation-with-mocks
|
// #docregion car-ctor-instantiation-with-mocks
|
||||||
class MockEngine extends Engine { cylinders = 8; }
|
class MockEngine extends Engine { cylinders = 8; }
|
||||||
class MockTires extends Tires { make = "YokoGoodStone"; }
|
class MockTires extends Tires { make = 'YokoGoodStone'; }
|
||||||
|
|
||||||
//#enddocregion car-ctor-instantiation-with-mocks
|
// #enddocregion car-ctor-instantiation-with-mocks
|
||||||
export function testCar() {
|
export function testCar() {
|
||||||
//#docregion car-ctor-instantiation-with-mocks
|
// #docregion car-ctor-instantiation-with-mocks
|
||||||
// Test car with 8 cylinders and YokoGoodStone tires.
|
// Test car with 8 cylinders and YokoGoodStone tires.
|
||||||
var car = new Car(new MockEngine(), new MockTires());
|
let car = new Car(new MockEngine(), new MockTires());
|
||||||
//#enddocregion car-ctor-instantiation-with-mocks
|
// #enddocregion car-ctor-instantiation-with-mocks
|
||||||
car.description = 'Test';
|
car.description = 'Test';
|
||||||
return car;
|
return car;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,23 +5,23 @@ import { Logger } from '../logger.service';
|
||||||
|
|
||||||
// #docregion injector
|
// #docregion injector
|
||||||
export function useInjector() {
|
export function useInjector() {
|
||||||
var injector: ReflectiveInjector;
|
let injector: ReflectiveInjector;
|
||||||
// #enddocregion injector
|
// #enddocregion injector
|
||||||
/*
|
/*
|
||||||
// #docregion injector-no-new
|
// #docregion injector-no-new
|
||||||
// Cannot instantiate an ReflectiveInjector like this!
|
// Cannot instantiate an ReflectiveInjector like this!
|
||||||
var injector = new ReflectiveInjector([Car, Engine, Tires]);
|
let injector = new ReflectiveInjector([Car, Engine, Tires]);
|
||||||
// #enddocregion injector-no-new
|
// #enddocregion injector-no-new
|
||||||
*/
|
*/
|
||||||
// #docregion injector, injector-create-and-call
|
// #docregion injector, injector-create-and-call
|
||||||
injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]);
|
injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]);
|
||||||
// #docregion injector-call
|
// #docregion injector-call
|
||||||
var car = injector.get(Car);
|
let car = injector.get(Car);
|
||||||
// #enddocregion injector-call, injector-create-and-call
|
// #enddocregion injector-call, injector-create-and-call
|
||||||
car.description = 'Injector';
|
car.description = 'Injector';
|
||||||
|
|
||||||
injector = ReflectiveInjector.resolveAndCreate([Logger]);
|
injector = ReflectiveInjector.resolveAndCreate([Logger]);
|
||||||
var logger = injector.get(Logger);
|
let logger = injector.get(Logger);
|
||||||
logger.log('Injector car.drive() said: '+car.drive());
|
logger.log('Injector car.drive() said: ' + car.drive());
|
||||||
return car;
|
return car;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
// Car without DI
|
// Car without DI
|
||||||
import { Engine, Tires } from './car';
|
import { Engine, Tires } from './car';
|
||||||
|
|
||||||
//#docregion car
|
// #docregion car
|
||||||
export class Car {
|
export class Car {
|
||||||
|
|
||||||
//#docregion car-ctor
|
// #docregion car-ctor
|
||||||
public engine: Engine;
|
public engine: Engine;
|
||||||
public tires: Tires;
|
public tires: Tires;
|
||||||
public description = 'No DI';
|
public description = 'No DI';
|
||||||
|
@ -13,12 +13,12 @@ export class Car {
|
||||||
this.engine = new Engine();
|
this.engine = new Engine();
|
||||||
this.tires = new Tires();
|
this.tires = new Tires();
|
||||||
}
|
}
|
||||||
//#enddocregion car-ctor
|
// #enddocregion car-ctor
|
||||||
|
|
||||||
// Method using the engine and tires
|
// Method using the engine and tires
|
||||||
drive() {
|
drive() {
|
||||||
return `${this.description} car with ` +
|
return `${this.description} car with ` +
|
||||||
`${this.engine.cylinders} cylinders and ${this.tires.make} tires.`
|
`${this.engine.cylinders} cylinders and ${this.tires.make} tires.`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#enddocregion car
|
// #enddocregion car
|
||||||
|
|
|
@ -11,7 +11,7 @@ export class Tires {
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class Car {
|
export class Car {
|
||||||
//#docregion car-ctor
|
// #docregion car-ctor
|
||||||
public description = 'DI';
|
public description = 'DI';
|
||||||
|
|
||||||
constructor(public engine: Engine, public tires: Tires) { }
|
constructor(public engine: Engine, public tires: Tires) { }
|
||||||
|
@ -20,6 +20,6 @@ export class Car {
|
||||||
// Method using the engine and tires
|
// Method using the engine and tires
|
||||||
drive() {
|
drive() {
|
||||||
return `${this.description} car with ` +
|
return `${this.description} car with ` +
|
||||||
`${this.engine.cylinders} cylinders and ${this.tires.make} tires.`
|
`${this.engine.cylinders} cylinders and ${this.tires.make} tires.`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* tslint:disable:one-line */
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,12 @@ import { Logger } from '../logger.service';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class HeroService {
|
export class HeroService {
|
||||||
|
|
||||||
//#docregion ctor
|
// #docregion ctor
|
||||||
constructor(private logger: Logger) { }
|
constructor(private logger: Logger) { }
|
||||||
//#enddocregion ctor
|
// #enddocregion ctor
|
||||||
|
|
||||||
getHeroes() {
|
getHeroes() {
|
||||||
this.logger.log('Getting heroes ...')
|
this.logger.log('Getting heroes ...');
|
||||||
return HEROES;
|
return HEROES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* tslint:disable:one-line */
|
||||||
// #docregion
|
// #docregion
|
||||||
import { HeroService } from './hero.service';
|
import { HeroService } from './hero.service';
|
||||||
import { Logger } from '../logger.service';
|
import { Logger } from '../logger.service';
|
||||||
|
@ -6,7 +7,7 @@ import { UserService } from '../user.service';
|
||||||
// #docregion factory
|
// #docregion factory
|
||||||
let heroServiceFactory = (logger: Logger, userService: UserService) => {
|
let heroServiceFactory = (logger: Logger, userService: UserService) => {
|
||||||
return new HeroService(logger, userService.user.isAuthorized);
|
return new HeroService(logger, userService.user.isAuthorized);
|
||||||
}
|
};
|
||||||
// #enddocregion factory
|
// #enddocregion factory
|
||||||
|
|
||||||
// #docregion provider
|
// #docregion provider
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Logger } from '../logger.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class HeroService {
|
export class HeroService {
|
||||||
private _user:string;
|
private _user: string;
|
||||||
|
|
||||||
// #docregion internals
|
// #docregion internals
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -15,7 +15,7 @@ export class HeroService {
|
||||||
private isAuthorized: boolean) { }
|
private isAuthorized: boolean) { }
|
||||||
|
|
||||||
getHeroes() {
|
getHeroes() {
|
||||||
let auth = this.isAuthorized ? 'authorized ': 'unauthorized';
|
let auth = this.isAuthorized ? 'authorized ' : 'unauthorized';
|
||||||
this.logger.log(`Getting heroes for ${auth} user.`);
|
this.logger.log(`Getting heroes for ${auth} user.`);
|
||||||
return HEROES.filter(hero => this.isAuthorized || !hero.isSecret);
|
return HEROES.filter(hero => this.isAuthorized || !hero.isSecret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ import { HeroService } from './hero.service';
|
||||||
<hero-list></hero-list>
|
<hero-list></hero-list>
|
||||||
`,
|
`,
|
||||||
// #enddocregion v1
|
// #enddocregion v1
|
||||||
providers:[HeroService],
|
providers: [HeroService],
|
||||||
// #docregion v1
|
// #docregion v1
|
||||||
directives:[HeroListComponent]
|
directives: [HeroListComponent]
|
||||||
})
|
})
|
||||||
export class HeroesComponent { }
|
export class HeroesComponent { }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { HeroListComponent } from './hero-list.component';
|
import { HeroListComponent } from './hero-list.component';
|
||||||
import { heroServiceProvider} from './hero.service.provider';
|
import { heroServiceProvider } from './hero.service.provider';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-heroes',
|
selector: 'my-heroes',
|
||||||
|
@ -10,7 +10,7 @@ import { heroServiceProvider} from './hero.service.provider';
|
||||||
<h2>Heroes</h2>
|
<h2>Heroes</h2>
|
||||||
<hero-list></hero-list>
|
<hero-list></hero-list>
|
||||||
`,
|
`,
|
||||||
providers:[heroServiceProvider],
|
providers: [heroServiceProvider],
|
||||||
directives:[HeroListComponent]
|
directives: [HeroListComponent]
|
||||||
})
|
})
|
||||||
export class HeroesComponent { }
|
export class HeroesComponent { }
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
import { Hero } from './hero';
|
import { Hero } from './hero';
|
||||||
|
|
||||||
export var HEROES: Hero[] = [
|
export var HEROES: Hero[] = [
|
||||||
{ id: 11, isSecret: false, name: "Mr. Nice" },
|
{ id: 11, isSecret: false, name: 'Mr. Nice' },
|
||||||
{ id: 12, isSecret: false, name: "Narco" },
|
{ id: 12, isSecret: false, name: 'Narco' },
|
||||||
{ id: 13, isSecret: false, name: "Bombasto" },
|
{ id: 13, isSecret: false, name: 'Bombasto' },
|
||||||
{ id: 14, isSecret: false, name: "Celeritas" },
|
{ id: 14, isSecret: false, name: 'Celeritas' },
|
||||||
{ id: 15, isSecret: false, name: "Magneta" },
|
{ id: 15, isSecret: false, name: 'Magneta' },
|
||||||
{ id: 16, isSecret: false, name: "RubberMan" },
|
{ id: 16, isSecret: false, name: 'RubberMan' },
|
||||||
{ id: 17, isSecret: false, name: "Dynama" },
|
{ id: 17, isSecret: false, name: 'Dynama' },
|
||||||
{ id: 18, isSecret: true, name: "Dr IQ" },
|
{ id: 18, isSecret: true, name: 'Dr IQ' },
|
||||||
{ id: 19, isSecret: true, name: "Magma" },
|
{ id: 19, isSecret: true, name: 'Magma' },
|
||||||
{ id: 20, isSecret: true, name: "Tornado" }
|
{ id: 20, isSecret: true, name: 'Tornado' }
|
||||||
];
|
];
|
||||||
|
|
|
@ -20,8 +20,6 @@ import { Logger } from './logger.service';
|
||||||
providers: [Car, Engine, Tires, heroServiceProvider, Logger]
|
providers: [Car, Engine, Tires, heroServiceProvider, Logger]
|
||||||
})
|
})
|
||||||
export class InjectorComponent {
|
export class InjectorComponent {
|
||||||
constructor(private injector: Injector) { }
|
|
||||||
|
|
||||||
car: Car = this.injector.get(Car);
|
car: Car = this.injector.get(Car);
|
||||||
|
|
||||||
// #docregion get-hero-service
|
// #docregion get-hero-service
|
||||||
|
@ -29,8 +27,10 @@ export class InjectorComponent {
|
||||||
// #enddocregion get-hero-service
|
// #enddocregion get-hero-service
|
||||||
hero: Hero = this.heroService.getHeroes()[0];
|
hero: Hero = this.heroService.getHeroes()[0];
|
||||||
|
|
||||||
|
constructor(private injector: Injector) { }
|
||||||
|
|
||||||
get rodent() {
|
get rodent() {
|
||||||
let rousDontExist = "R.O.U.S.'s? I don't think they exist!";
|
let rousDontExist = `R.O.U.S.'s? I don't think they exist!`;
|
||||||
return this.injector.get(ROUS, rousDontExist);
|
return this.injector.get(ROUS, rousDontExist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class Logger {
|
export class Logger {
|
||||||
logs:string[] = []; // capture logs for testing
|
logs: string[] = []; // capture logs for testing
|
||||||
|
|
||||||
log(message: string) {
|
log(message: string) {
|
||||||
this.logs.push(message);
|
this.logs.push(message);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* tslint:disable:no-unused-variable */
|
||||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||||
import { AppComponent } from './app.component.1';
|
import { AppComponent } from './app.component.1';
|
||||||
import { HeroService } from './heroes/hero.service.1';
|
import { HeroService } from './heroes/hero.service.1';
|
||||||
|
@ -5,9 +6,8 @@ import { HeroService } from './heroes/hero.service.1';
|
||||||
bootstrap(AppComponent);
|
bootstrap(AppComponent);
|
||||||
|
|
||||||
function discouraged() {
|
function discouraged() {
|
||||||
//#docregion bootstrap
|
// #docregion bootstrap-discouraged
|
||||||
bootstrap(AppComponent,
|
bootstrap(AppComponent,
|
||||||
[HeroService]); // DISCOURAGED (but works)不推荐(但可用)
|
[HeroService]); // DISCOURAGED (but works)
|
||||||
//#enddocregion bootstrap
|
// #enddocregion bootstrap-discouraged
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { ProvidersComponent } from './providers.component';
|
import { ProvidersComponent } from './providers.component';
|
||||||
|
|
||||||
//#docregion bootstrap
|
// #docregion bootstrap
|
||||||
bootstrap(AppComponent);
|
bootstrap(AppComponent);
|
||||||
//#enddocregion bootstrap
|
// #enddocregion bootstrap
|
||||||
bootstrap(ProvidersComponent);
|
bootstrap(ProvidersComponent);
|
||||||
|
|
|
@ -235,8 +235,9 @@ export class ProviderComponent10 {
|
||||||
log: string;
|
log: string;
|
||||||
// #docregion provider-10-ctor
|
// #docregion provider-10-ctor
|
||||||
constructor(@Optional() private logger: Logger) {
|
constructor(@Optional() private logger: Logger) {
|
||||||
if (this.logger)
|
if (this.logger) {
|
||||||
this.logger.log(some_message);
|
this.logger.log(some_message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// #enddocregion provider-10-ctor
|
// #enddocregion provider-10-ctor
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* tslint:disable */
|
||||||
// Simulate a simple test
|
// Simulate a simple test
|
||||||
// Reader should look to the testing chapter for the real thing
|
// Reader should look to the testing chapter for the real thing
|
||||||
|
|
||||||
|
@ -20,15 +21,15 @@ export class TestComponent {
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
function runTests() {
|
function runTests() {
|
||||||
|
|
||||||
//#docregion spec
|
// #docregion spec
|
||||||
let expectedHeroes = [{name: 'A'}, {name: 'B'}]
|
let expectedHeroes = [{name: 'A'}, {name: 'B'}]
|
||||||
let mockService = <HeroService> {getHeroes: () => expectedHeroes }
|
let mockService = <HeroService> {getHeroes: () => expectedHeroes }
|
||||||
|
|
||||||
it("should have heroes when HeroListComponent created", () => {
|
it('should have heroes when HeroListComponent created', () => {
|
||||||
let hlc = new HeroListComponent(mockService);
|
let hlc = new HeroListComponent(mockService);
|
||||||
expect(hlc.heroes.length).toEqual(expectedHeroes.length);
|
expect(hlc.heroes.length).toEqual(expectedHeroes.length);
|
||||||
})
|
});
|
||||||
//#enddocregion spec
|
// #enddocregion spec
|
||||||
|
|
||||||
return testResults;
|
return testResults;
|
||||||
}
|
}
|
||||||
|
@ -36,19 +37,19 @@ function runTests() {
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
// Fake Jasmine infrastructure
|
// Fake Jasmine infrastructure
|
||||||
var testName: string;
|
var testName: string;
|
||||||
var testResults: {pass:string; message:string};
|
var testResults: {pass: string; message: string};
|
||||||
|
|
||||||
function expect(actual:any) {
|
function expect(actual: any) {
|
||||||
return {
|
return {
|
||||||
toEqual: function(expected:any){
|
toEqual: function(expected: any){
|
||||||
testResults = actual === expected?
|
testResults = actual === expected ?
|
||||||
{pass:'passed', message: testName} :
|
{pass: 'passed', message: testName} :
|
||||||
{pass:'failed', message: `${testName}; expected ${actual} to equal ${expected}.`};
|
{pass: 'failed', message: `${testName}; expected ${actual} to equal ${expected}.`};
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function it(label:string, test: () => void) {
|
function it(label: string, test: () => void) {
|
||||||
testName = label;
|
testName = label;
|
||||||
test();
|
test();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import {Injectable} from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
export class User {
|
export class User {
|
||||||
constructor(
|
constructor(
|
||||||
public name:string,
|
public name: string,
|
||||||
public isAuthorized:boolean = false) { }
|
public isAuthorized = false) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: get the user; don't 'new' it.
|
// Todo: get the user; don't 'new' it.
|
||||||
|
|
|
@ -17,4 +17,4 @@ export class AppCtorComponent {
|
||||||
this.myHero = 'Windstorm';
|
this.myHero = 'Windstorm';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #enddocregion app-ctor
|
// #enddocregion app-ctor
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component} from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
// #docregion import-hero
|
// #docregion import-hero
|
||||||
import { Hero} from './hero';
|
import { Hero } from './hero';
|
||||||
// #enddocregion import-hero
|
// #enddocregion import-hero
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
export class Hero {
|
export class Hero {
|
||||||
constructor(
|
constructor(
|
||||||
// #docregion id-parameter
|
// #docregion id-parameter
|
||||||
public id:number,
|
public id: number,
|
||||||
// #enddocregion id-parameter
|
// #enddocregion id-parameter
|
||||||
public name:string) { }
|
public name: string) { }
|
||||||
}
|
}
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* tslint:disable */
|
||||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
import { AppCtorComponent } from './app-ctor.component';
|
import { AppCtorComponent } from './app-ctor.component';
|
||||||
|
@ -8,9 +9,9 @@ import { AppComponent as v3 } from './app.component.3';
|
||||||
import { AppComponent as final } from './app.component';
|
import { AppComponent as final } from './app.component';
|
||||||
|
|
||||||
// pick one
|
// pick one
|
||||||
//bootstrap(v1);
|
// bootstrap(v1);
|
||||||
//bootstrap(v2);
|
// bootstrap(v2);
|
||||||
//bootstrap(v3);
|
// bootstrap(v3);
|
||||||
bootstrap(final);
|
bootstrap(final);
|
||||||
|
|
||||||
// for doc testing
|
// for doc testing
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { HeroFormComponent } from './hero-form.component'
|
import { HeroFormComponent } from './hero-form.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-app',
|
selector: 'my-app',
|
||||||
|
|
|
@ -41,7 +41,7 @@ export class HeroFormComponent {
|
||||||
this.model = new Hero(42, '', '');
|
this.model = new Hero(42, '', '');
|
||||||
// #enddocregion new-hero-v1
|
// #enddocregion new-hero-v1
|
||||||
this.active = false;
|
this.active = false;
|
||||||
setTimeout(()=> this.active=true, 0);
|
setTimeout(() => this.active = true, 0);
|
||||||
// #docregion new-hero-v1
|
// #docregion new-hero-v1
|
||||||
}
|
}
|
||||||
// #enddocregion new-hero-v1
|
// #enddocregion new-hero-v1
|
||||||
|
@ -51,7 +51,7 @@ export class HeroFormComponent {
|
||||||
|
|
||||||
// Reveal in html:
|
// Reveal in html:
|
||||||
// Name via form.controls = {{showFormControls(heroForm)}}
|
// Name via form.controls = {{showFormControls(heroForm)}}
|
||||||
showFormControls(form:NgForm){
|
showFormControls(form: NgForm) {
|
||||||
|
|
||||||
return form && form.controls['name'] &&
|
return form && form.controls['name'] &&
|
||||||
// #docregion form-controls
|
// #docregion form-controls
|
||||||
|
|
|
@ -6,8 +6,8 @@ describe('Hierarchical dependency injection', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open with a card view', function () {
|
it('should open with a card view', function () {
|
||||||
expect(element.all(by.cssContainingText('button','edit')).get(0).isDisplayed()).toBe(true,
|
expect(element.all(by.cssContainingText('button', 'edit')).get(0).isDisplayed()).toBe(true,
|
||||||
"edit button should be displayed");
|
'edit button should be displayed');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have multiple heroes listed', function () {
|
it('should have multiple heroes listed', function () {
|
||||||
|
@ -15,10 +15,10 @@ describe('Hierarchical dependency injection', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change to editor view after selection', function () {
|
it('should change to editor view after selection', function () {
|
||||||
let editButtonEle = element.all(by.cssContainingText('button','edit')).get(0);
|
let editButtonEle = element.all(by.cssContainingText('button', 'edit')).get(0);
|
||||||
editButtonEle.click().then(function() {
|
editButtonEle.click().then(function() {
|
||||||
expect(editButtonEle.isDisplayed()).toBe(false, "edit button should be hidden after selection");
|
expect(editButtonEle.isDisplayed()).toBe(false, 'edit button should be hidden after selection');
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to save editor change', function () {
|
it('should be able to save editor change', function () {
|
||||||
|
@ -34,11 +34,11 @@ describe('Hierarchical dependency injection', function () {
|
||||||
let heroEle = element.all(by.css('heroes-list li')).get(1);
|
let heroEle = element.all(by.css('heroes-list li')).get(1);
|
||||||
// get the 2nd span which is the name of the hero
|
// get the 2nd span which is the name of the hero
|
||||||
let heroNameEle = heroEle.all(by.css('hero-card span')).get(1);
|
let heroNameEle = heroEle.all(by.css('hero-card span')).get(1);
|
||||||
let editButtonEle = heroEle.element(by.cssContainingText('button','edit'));
|
let editButtonEle = heroEle.element(by.cssContainingText('button', 'edit'));
|
||||||
editButtonEle.click().then(function() {
|
editButtonEle.click().then(function() {
|
||||||
let inputEle = heroEle.element(by.css('hero-editor input'));
|
let inputEle = heroEle.element(by.css('hero-editor input'));
|
||||||
// return inputEle.sendKeys("foo");
|
// return inputEle.sendKeys("foo");
|
||||||
return sendKeys(inputEle, "foo");
|
return sendKeys(inputEle, 'foo');
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
let buttonName = shouldSave ? 'save' : 'cancel';
|
let buttonName = shouldSave ? 'save' : 'cancel';
|
||||||
let buttonEle = heroEle.element(by.cssContainingText('button', buttonName));
|
let buttonEle = heroEle.element(by.cssContainingText('button', buttonName));
|
||||||
|
@ -49,7 +49,7 @@ describe('Hierarchical dependency injection', function () {
|
||||||
} else {
|
} else {
|
||||||
expect(heroNameEle.getText()).not.toContain('foo');
|
expect(heroNameEle.getText()).not.toContain('foo');
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
export class EditItem<T> {
|
export class EditItem<T> {
|
||||||
editing: boolean
|
editing: boolean;
|
||||||
constructor (public item: T) {}
|
constructor (public item: T) {}
|
||||||
}
|
}
|
||||||
// #docregion
|
// #docregion
|
||||||
|
|
|
@ -2,8 +2,8 @@ import { Hero } from './hero';
|
||||||
|
|
||||||
export class HeroesService {
|
export class HeroesService {
|
||||||
heroes: Array<Hero> = [
|
heroes: Array<Hero> = [
|
||||||
{ name: "RubberMan", power: 'flexibility'},
|
{ name: 'RubberMan', power: 'flexibility'},
|
||||||
{ name: "Tornado", power: 'Weather changer'}
|
{ name: 'Tornado', power: 'Weather changer'}
|
||||||
];
|
];
|
||||||
|
|
||||||
getHeroes () {
|
getHeroes () {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||||
import { HeroesListComponent } from './heroes-list.component';
|
import { HeroesListComponent } from './heroes-list.component';
|
||||||
import { HeroesService } from './heroes.service';
|
import { HeroesService } from './heroes.service';
|
||||||
|
|
||||||
bootstrap(HeroesListComponent, [HeroesService])
|
bootstrap(HeroesListComponent, [HeroesService]);
|
||||||
|
|
||||||
/* Documentation artifact below
|
/* Documentation artifact below
|
||||||
// #docregion bad-alternative
|
// #docregion bad-alternative
|
||||||
|
|
|
@ -8,16 +8,16 @@ export class RestoreService<T> {
|
||||||
this.currentItem = this.clone(item);
|
this.currentItem = this.clone(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
getItem () :T {
|
getItem (): T {
|
||||||
return this.currentItem;
|
return this.currentItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
restoreItem () :T {
|
restoreItem (): T {
|
||||||
this.currentItem = this.originalItem;
|
this.currentItem = this.originalItem;
|
||||||
return this.getItem();
|
return this.getItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
clone (item: T) :T {
|
clone (item: T): T {
|
||||||
// super poor clone implementation
|
// super poor clone implementation
|
||||||
return JSON.parse(JSON.stringify(item));
|
return JSON.parse(JSON.stringify(item));
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ describe('Homepage Hello World', function () {
|
||||||
it(`should display the label: ${expectedLabel}`, function () {
|
it(`should display the label: ${expectedLabel}`, function () {
|
||||||
expect(element(by.css('label')).getText()).toEqual(expectedLabel);
|
expect(element(by.css('label')).getText()).toEqual(expectedLabel);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display entered name', function () {
|
it('should display entered name', function () {
|
||||||
let testName = 'Bobby Joe';
|
let testName = 'Bobby Joe';
|
||||||
let nameEle = element.all(by.css('input')).get(0);
|
let nameEle = element.all(by.css('input')).get(0);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
// Declare an interaface for type safety
|
// Declare an interaface for type safety
|
||||||
export interface Todo {
|
export interface Todo {
|
||||||
text: string,
|
text: string;
|
||||||
done: boolean
|
done: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { TodoForm } from './todo_form';
|
||||||
|
|
||||||
<todo-list [todos]="todos"></todo-list>
|
<todo-list [todos]="todos"></todo-list>
|
||||||
<todo-form (newTask)="addTask($event)"></todo-form>`,
|
<todo-form (newTask)="addTask($event)"></todo-form>`,
|
||||||
styles:['a { cursor: pointer; cursor: hand; }'],
|
styles: ['a { cursor: pointer; cursor: hand; }'],
|
||||||
directives: [TodoList, TodoForm]
|
directives: [TodoList, TodoForm]
|
||||||
})
|
})
|
||||||
export class TodoApp {
|
export class TodoApp {
|
||||||
|
|
|
@ -17,7 +17,7 @@ export class TodoForm {
|
||||||
|
|
||||||
addTodo() {
|
addTodo() {
|
||||||
if (this.task) {
|
if (this.task) {
|
||||||
this.newTask.next({text:this.task, done:false});
|
this.newTask.next({text: this.task, done: false});
|
||||||
}
|
}
|
||||||
this.task = '';
|
this.task = '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
import { Todo } from './todo';
|
import { Todo } from './todo';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|
|
@ -11,22 +11,22 @@ describe('Lifecycle hooks', function () {
|
||||||
|
|
||||||
it('should support peek-a-boo', function () {
|
it('should support peek-a-boo', function () {
|
||||||
let pabComp = element(by.css('peek-a-boo-parent peek-a-boo'));
|
let pabComp = element(by.css('peek-a-boo-parent peek-a-boo'));
|
||||||
expect(pabComp.isPresent()).toBe(false, "should not be able to find the 'peek-a-boo' component");
|
expect(pabComp.isPresent()).toBe(false, 'should not be able to find the "peek-a-boo" component');
|
||||||
let pabButton = element.all(by.css('peek-a-boo-parent button')).get(0);
|
let pabButton = element.all(by.css('peek-a-boo-parent button')).get(0);
|
||||||
let updateHeroButton = element.all(by.css('peek-a-boo-parent button')).get(1);
|
let updateHeroButton = element.all(by.css('peek-a-boo-parent button')).get(1);
|
||||||
expect(pabButton.getText()).toContain('Create Peek');
|
expect(pabButton.getText()).toContain('Create Peek');
|
||||||
pabButton.click().then(function () {
|
pabButton.click().then(function () {
|
||||||
expect(pabButton.getText()).toContain('Destroy Peek');
|
expect(pabButton.getText()).toContain('Destroy Peek');
|
||||||
expect(pabComp.isDisplayed()).toBe(true, "should be able to see the 'peek-a-boo' component");
|
expect(pabComp.isDisplayed()).toBe(true, 'should be able to see the "peek-a-boo" component');
|
||||||
expect(pabComp.getText()).toContain('Windstorm');
|
expect(pabComp.getText()).toContain('Windstorm');
|
||||||
expect(pabComp.getText()).not.toContain('Windstorm!');
|
expect(pabComp.getText()).not.toContain('Windstorm!');
|
||||||
expect(updateHeroButton.isPresent()).toBe(true, "should be able to see the update hero button");
|
expect(updateHeroButton.isPresent()).toBe(true, 'should be able to see the update hero button');
|
||||||
return updateHeroButton.click();
|
return updateHeroButton.click();
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
expect(pabComp.getText()).toContain('Windstorm!');
|
expect(pabComp.getText()).toContain('Windstorm!');
|
||||||
return pabButton.click();
|
return pabButton.click();
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
expect(pabComp.isPresent()).toBe(false, "should no longer be able to find the 'peek-a-boo' component");
|
expect(pabComp.isPresent()).toBe(false, 'should no longer be able to find the "peek-a-boo" component');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -39,18 +39,18 @@ describe('Lifecycle hooks', function () {
|
||||||
let changeLogEles = onChangesViewEle.all(by.css('div'));
|
let changeLogEles = onChangesViewEle.all(by.css('div'));
|
||||||
|
|
||||||
expect(titleEle.getText()).toContain('Windstorm can sing');
|
expect(titleEle.getText()).toContain('Windstorm can sing');
|
||||||
expect(changeLogEles.count()).toEqual(2, "should start with 2 messages");
|
expect(changeLogEles.count()).toEqual(2, 'should start with 2 messages');
|
||||||
// heroNameInputEle.sendKeys('-foo-').then(function () {
|
// heroNameInputEle.sendKeys('-foo-').then(function () {
|
||||||
sendKeys(heroNameInputEle, '-foo-').then(function () {
|
sendKeys(heroNameInputEle, '-foo-').then(function () {
|
||||||
expect(titleEle.getText()).toContain('Windstorm-foo- can sing');
|
expect(titleEle.getText()).toContain('Windstorm-foo- can sing');
|
||||||
expect(changeLogEles.count()).toEqual(2, "should still have 2 messages");
|
expect(changeLogEles.count()).toEqual(2, 'should still have 2 messages');
|
||||||
// protractor bug with sendKeys means that line below does not work.
|
// protractor bug with sendKeys means that line below does not work.
|
||||||
// return powerInputEle.sendKeys('-bar-');
|
// return powerInputEle.sendKeys('-bar-');
|
||||||
return sendKeys(powerInputEle, '-bar-');
|
return sendKeys(powerInputEle, '-bar-');
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
expect(titleEle.getText()).toContain('Windstorm-foo- can sing-bar-');
|
expect(titleEle.getText()).toContain('Windstorm-foo- can sing-bar-');
|
||||||
// 7 == 2 previously + length of '-bar-'
|
// 7 == 2 previously + length of '-bar-'
|
||||||
expect(changeLogEles.count()).toEqual(7, "should have 7 messages now");
|
expect(changeLogEles.count()).toEqual(7, 'should have 7 messages now');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -66,16 +66,16 @@ describe('Lifecycle hooks', function () {
|
||||||
expect(titleEle.getText()).toContain('Windstorm can sing');
|
expect(titleEle.getText()).toContain('Windstorm can sing');
|
||||||
changeLogEles.count().then(function(count) {
|
changeLogEles.count().then(function(count) {
|
||||||
// Empirically 5 messages to start
|
// Empirically 5 messages to start
|
||||||
expect(count).toBeGreaterThan(4, "should start with some messages");
|
expect(count).toBeGreaterThan(4, 'should start with some messages');
|
||||||
logCount = count;
|
logCount = count;
|
||||||
// heroNameInputEle.sendKeys('-foo-').then(function () {
|
// heroNameInputEle.sendKeys('-foo-').then(function () {
|
||||||
return sendKeys(heroNameInputEle, '-foo-')
|
return sendKeys(heroNameInputEle, '-foo-');
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
expect(titleEle.getText()).toContain('Windstorm-foo- can sing');
|
expect(titleEle.getText()).toContain('Windstorm-foo- can sing');
|
||||||
return changeLogEles.count()
|
return changeLogEles.count();
|
||||||
}).then(function (count) {
|
}).then(function (count) {
|
||||||
// two more for each keystroke except the 1st
|
// two more for each keystroke except the 1st
|
||||||
expect(count).toEqual(logCount + 9, 'should add 9 more messages')
|
expect(count).toEqual(logCount + 9, 'should add 9 more messages');
|
||||||
logCount = count;
|
logCount = count;
|
||||||
// return powerInputEle.sendKeys('-bar-');
|
// return powerInputEle.sendKeys('-bar-');
|
||||||
return sendKeys(powerInputEle, '-bar-');
|
return sendKeys(powerInputEle, '-bar-');
|
||||||
|
@ -99,18 +99,18 @@ describe('Lifecycle hooks', function () {
|
||||||
|
|
||||||
logEles.count().then(function(count) {
|
logEles.count().then(function(count) {
|
||||||
logCount = count;
|
logCount = count;
|
||||||
return sendKeys(childViewInputEle, "-test-");
|
return sendKeys(childViewInputEle, '-test-');
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
expect(childViewInputEle.getAttribute('value')).toContain('-test-');
|
expect(childViewInputEle.getAttribute('value')).toContain('-test-');
|
||||||
expect(commentEle.isPresent()).toBe(true,'should have comment because >10 chars');
|
expect(commentEle.isPresent()).toBe(true, 'should have comment because >10 chars');
|
||||||
expect(commentEle.getText()).toContain('long name');
|
expect(commentEle.getText()).toContain('long name');
|
||||||
return logEles.count();
|
return logEles.count();
|
||||||
}).then(function(count) {
|
}).then(function(count) {
|
||||||
expect(logCount + 10).toEqual(count, "10 additional log messages should have been added");
|
expect(logCount + 10).toEqual(count, '10 additional log messages should have been added');
|
||||||
logCount = count;
|
logCount = count;
|
||||||
return buttonEle.click();
|
return buttonEle.click();
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
expect(logEles.count()).toBeLessThan(logCount, "log should shrink after reset");
|
expect(logEles.count()).toBeLessThan(logCount, 'log should shrink after reset');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -128,30 +128,30 @@ describe('Lifecycle hooks', function () {
|
||||||
|
|
||||||
logEles.count().then(function(count) {
|
logEles.count().then(function(count) {
|
||||||
logCount = count;
|
logCount = count;
|
||||||
return sendKeys(childViewInputEle, "-test-");
|
return sendKeys(childViewInputEle, '-test-');
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
expect(childViewInputEle.getAttribute('value')).toContain('-test-');
|
expect(childViewInputEle.getAttribute('value')).toContain('-test-');
|
||||||
expect(commentEle.isPresent()).toBe(true,'should have comment because >10 chars');
|
expect(commentEle.isPresent()).toBe(true, 'should have comment because >10 chars');
|
||||||
expect(commentEle.getText()).toContain('long name');
|
expect(commentEle.getText()).toContain('long name');
|
||||||
return logEles.count();
|
return logEles.count();
|
||||||
}).then(function(count) {
|
}).then(function(count) {
|
||||||
expect(logCount + 10).toEqual(count, "10 additional log messages should have been added");
|
expect(logCount + 10).toEqual(count, '10 additional log messages should have been added');
|
||||||
logCount = count;
|
logCount = count;
|
||||||
return buttonEle.click();
|
return buttonEle.click();
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
expect(logEles.count()).toBeLessThan(logCount, "log should shrink after reset");
|
expect(logEles.count()).toBeLessThan(logCount, 'log should shrink after reset');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support spy\'s OnInit & OnDestroy hooks', function () {
|
it('should support spy\'s OnInit & OnDestroy hooks', function () {
|
||||||
let inputEle = element(by.css('spy-parent input'));
|
let inputEle = element(by.css('spy-parent input'));
|
||||||
let addHeroButtonEle = element(by.cssContainingText('spy-parent button','Add Hero'));
|
let addHeroButtonEle = element(by.cssContainingText('spy-parent button', 'Add Hero'));
|
||||||
let resetHeroesButtonEle = element(by.cssContainingText('spy-parent button','Reset Heroes'));
|
let resetHeroesButtonEle = element(by.cssContainingText('spy-parent button', 'Reset Heroes'));
|
||||||
let heroEles = element.all(by.css('spy-parent div[mySpy'));
|
let heroEles = element.all(by.css('spy-parent div[mySpy'));
|
||||||
let logEles = element.all(by.css('spy-parent h4 ~ div'));
|
let logEles = element.all(by.css('spy-parent h4 ~ div'));
|
||||||
expect(heroEles.count()).toBe(2, 'should have two heroes displayed');
|
expect(heroEles.count()).toBe(2, 'should have two heroes displayed');
|
||||||
expect(logEles.count()).toBe(2, 'should have two log entries');
|
expect(logEles.count()).toBe(2, 'should have two log entries');
|
||||||
sendKeys(inputEle, "-test-").then(function() {
|
sendKeys(inputEle, '-test-').then(function() {
|
||||||
return addHeroButtonEle.click();
|
return addHeroButtonEle.click();
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
expect(heroEles.count()).toBe(3, 'should have added one hero');
|
expect(heroEles.count()).toBe(3, 'should have added one hero');
|
||||||
|
@ -161,12 +161,12 @@ describe('Lifecycle hooks', function () {
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
expect(heroEles.count()).toBe(0, 'should no longer have any heroes');
|
expect(heroEles.count()).toBe(0, 'should no longer have any heroes');
|
||||||
expect(logEles.count()).toBe(7, 'should now have 7 log entries - 3 orig + 1 reset + 3 removeall');
|
expect(logEles.count()).toBe(7, 'should now have 7 log entries - 3 orig + 1 reset + 3 removeall');
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support "spy counter"', function () {
|
it('should support "spy counter"', function () {
|
||||||
let updateCounterButtonEle = element(by.cssContainingText('counter-parent button','Update'));
|
let updateCounterButtonEle = element(by.cssContainingText('counter-parent button', 'Update'));
|
||||||
let resetCounterButtonEle = element(by.cssContainingText('counter-parent button','Reset'));
|
let resetCounterButtonEle = element(by.cssContainingText('counter-parent button', 'Reset'));
|
||||||
let textEle = element(by.css('counter-parent my-counter > div'));
|
let textEle = element(by.css('counter-parent my-counter > div'));
|
||||||
let logEles = element.all(by.css('counter-parent h4 ~ div'));
|
let logEles = element.all(by.css('counter-parent h4 ~ div'));
|
||||||
expect(textEle.getText()).toContain('Counter = 0');
|
expect(textEle.getText()).toContain('Counter = 0');
|
||||||
|
@ -178,8 +178,6 @@ describe('Lifecycle hooks', function () {
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
expect(textEle.getText()).toContain('Counter = 0');
|
expect(textEle.getText()).toContain('Counter = 0');
|
||||||
expect(logEles.count()).toBe(7, 'should now have 7 log entries - 3 prev + 1 reset + 2 destroy + 1 init');
|
expect(logEles.count()).toBe(7, 'should now have 7 log entries - 3 prev + 1 reset + 2 destroy + 1 init');
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue