Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 4fa7bd0

Browse files
committed
docs(hierarchical-dependency-injection): heroes example as tax returns
1 parent 91e8c77 commit 4fa7bd0

18 files changed

+264
-193
lines changed

public/docs/_examples/hierarchical-dependency-injection/e2e-spec.ts

+24-27
Original file line numberDiff line numberDiff line change
@@ -11,73 +11,70 @@ describe('Hierarchical dependency injection', () => {
1111
describe('Heroes Scenario', () => {
1212
let page = {
1313
heroName: '',
14-
heroText: '',
14+
income: '',
1515

1616
// queries
1717
heroEl: element.all(by.css('heroes-list li')).get(0), // first hero
18-
heroCardEl: element(by.css('heroes-list hero-card')), // first hero card
19-
cardNameInputEl: element.all(by.css('heroes-list hero-card input')).get(0),
20-
cancelButtonEl: element(by.cssContainingText('heroes-list hero-card button', 'Cancel')),
21-
closeButtonEl: element(by.cssContainingText('heroes-list hero-card button', 'Close')),
22-
saveButtonEl: element(by.cssContainingText('heroes-list hero-card button', 'Save'))
18+
heroCardEl: element(by.css('heroes-list hero-tax-return')), // first hero tax-return
19+
taxReturnNameEl: element.all(by.css('heroes-list hero-tax-return #name')).get(0),
20+
incomeInputEl: element.all(by.css('heroes-list hero-tax-return input')).get(0),
21+
cancelButtonEl: element(by.cssContainingText('heroes-list hero-tax-return button', 'Cancel')),
22+
closeButtonEl: element(by.cssContainingText('heroes-list hero-tax-return button', 'Close')),
23+
saveButtonEl: element(by.cssContainingText('heroes-list hero-tax-return button', 'Save'))
2324
};
2425

2526
it('should list multiple heroes', () => {
2627
expect(element.all(by.css('heroes-list li')).count()).toBeGreaterThan(1);
2728
});
2829

29-
it('should show no hero cards at the start', () => {
30-
expect(element.all(by.css('heroes-list li hero-card')).count()).toBe(0);
30+
it('should show no hero tax-returns at the start', () => {
31+
expect(element.all(by.css('heroes-list li hero-tax-return')).count()).toBe(0);
3132
});
3233

33-
it('should open first hero in hero-card view after click', () => {
34+
it('should open first hero in hero-tax-return view after click', () => {
3435
page.heroEl.getText()
3536
.then(val => {
36-
// console.log('Selected hero text: ' + val);
37-
page.heroText = val;
38-
page.heroName = val.substring(0, val.indexOf('()') - 1);
37+
page.heroName = val;
3938
})
4039
.then(() => page.heroEl.click())
4140
.then(() => {
4241
expect(page.heroCardEl.isDisplayed()).toBe(true);
4342
});
4443
});
4544

46-
it('hero card should have first hero\'s name', () => {
47-
// Not `page.cardNameInputEl.getAttribute('value')` although later that is essential
48-
expect(page.cardNameInputEl.getText()).toEqual(page.heroName);
45+
it('hero tax-return should have first hero\'s name', () => {
46+
// Not `page.tax-returnNameInputEl.getAttribute('value')` although later that is essential
47+
expect(page.taxReturnNameEl.getText()).toEqual(page.heroName);
4948
});
5049

5150
it('should be able to cancel change', () => {
52-
page.cardNameInputEl.sendKeys('foo')
51+
page.incomeInputEl.clear()
52+
.then(() => page.incomeInputEl.sendKeys('777'))
5353
.then(() => {
54-
expect(page.cardNameInputEl.getAttribute('value')).toContain('foo', 'input name should have foo');
55-
expect(page.heroEl.getText()).toEqual(page.heroText, 'list text should be unchanged');
54+
expect(page.incomeInputEl.getAttribute('value')).toBe('777', 'income should be 777');
5655
return page.cancelButtonEl.click();
5756
})
5857
.then(() => {
59-
expect(page.cardNameInputEl.getAttribute('value')).not.toContain('foo', 'input name should not have foo');
60-
expect(page.heroEl.getText()).toEqual(page.heroText, 'list text should be unchanged');
58+
expect(page.incomeInputEl.getAttribute('value')).not.toBe('777', 'income should not be 777');
6159
});
6260
});
6361

6462
it('should be able to save change', () => {
65-
page.cardNameInputEl.sendKeys('bar')
63+
page.incomeInputEl.clear()
64+
.then(() => page.incomeInputEl.sendKeys('999'))
6665
.then(() => {
67-
expect(page.cardNameInputEl.getAttribute('value')).toContain('bar', 'input name should have bar');
68-
expect(page.heroEl.getText()).toEqual(page.heroText, 'list text should be unchanged');
66+
expect(page.incomeInputEl.getAttribute('value')).toBe('999', 'income should be 999');
6967
return page.saveButtonEl.click();
7068
})
7169
.then(() => {
72-
expect(page.cardNameInputEl.getAttribute('value')).toContain('bar', 'input name should still have bar');
73-
expect(page.heroEl.getText()).toContain('bar', 'list text should have changed to include bar');
70+
expect(page.incomeInputEl.getAttribute('value')).toBe('999', 'income should still be 999');
7471
});
7572
});
7673

77-
it('should be able to close card', () => {
74+
it('should be able to close tax-return', () => {
7875
page.saveButtonEl.click()
7976
.then(() => {
80-
expect(element.all(by.css('heroes-list li hero-card')).count()).toBe(0);
77+
expect(element.all(by.css('heroes-list li hero-tax-return')).count()).toBe(0);
8178
});
8279
});
8380

public/docs/_examples/hierarchical-dependency-injection/ts/app/app.module.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { BrowserModule } from '@angular/platform-browser';
44
import { FormsModule } from '@angular/forms';
55

66
import { AppComponent } from './app.component';
7-
import { HeroCardComponent } from './hero-card.component';
7+
import { HeroTaxReturnComponent } from './hero-tax-return.component';
88
import { HeroesListComponent } from './heroes-list.component';
99
import { HeroesService } from './heroes.service';
1010
import { VillainsListComponent } from './villains-list.component';
@@ -24,7 +24,7 @@ import { carComponents, carServices } from './car.components';
2424
AppComponent,
2525
carComponents,
2626
HeroesListComponent,
27-
HeroCardComponent,
27+
HeroTaxReturnComponent,
2828
VillainsListComponent
2929
],
3030
bootstrap: [ AppComponent ]

public/docs/_examples/hierarchical-dependency-injection/ts/app/hero-card.component.css

-3
This file was deleted.

public/docs/_examples/hierarchical-dependency-injection/ts/app/hero-card.component.html

-17
This file was deleted.

public/docs/_examples/hierarchical-dependency-injection/ts/app/hero-card.component.ts

-41
This file was deleted.

public/docs/_examples/hierarchical-dependency-injection/ts/app/hero-state.service.ts

-36
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.tax-return { border: thin dashed green; margin: 1em; padding: 1em; width: 18em; position: relative }
2+
#name { font-weight: bold;}
3+
#tid { float: right; }
4+
input { font-size: 100%; padding-left: 2px; width: 6em; }
5+
input.num { text-align: right; padding-left: 0; padding-right: 4px; width: 4em;}
6+
fieldset { border: 0 none;}
7+
8+
.msg {
9+
color: white;
10+
font-size: 150%;
11+
position: absolute;
12+
/*opacity: 0.3;*/
13+
left: 2px;
14+
top: 3em;
15+
width: 98%;
16+
background-color: green;
17+
text-align: center;
18+
}
19+
.msg.canceled {
20+
color: white;
21+
background-color: red;
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<div class="tax-return">
2+
<div class="msg" [class.canceled]="message==='Canceled'">{{message}}</div>
3+
<fieldset>
4+
<span id=name>{{taxReturn.name}}</span>
5+
<label id=tid>TID: {{taxReturn.tid}}</label>
6+
</fieldset>
7+
<fieldset>
8+
<label>
9+
Income: <input [(ngModel)]="taxReturn.income" class="num">
10+
</label>
11+
</fieldset>
12+
<fieldset>
13+
<label>Tax: {{taxReturn.tax}}</label>
14+
</fieldset>
15+
<fieldset>
16+
<button (click)="onSaved()">Save</button>
17+
<button (click)="onCanceled()">Cancel</button>
18+
<button (click)="onClose()">Close</button>
19+
</fieldset>
20+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// #docregion
2+
import { Component, EventEmitter, Input, Output } from '@angular/core';
3+
import { HeroTaxReturn } from './hero';
4+
import { HeroTaxReturnService } from './hero-tax-return.service';
5+
6+
@Component({
7+
moduleId: module.id,
8+
selector: 'hero-tax-return',
9+
templateUrl: './hero-tax-return.component.html',
10+
styleUrls: [ './hero-tax-return.component.css' ],
11+
// #docregion providers
12+
providers: [ HeroTaxReturnService ]
13+
// #enddocregion providers
14+
})
15+
export class HeroTaxReturnComponent {
16+
message = '';
17+
@Output() close = new EventEmitter<void>();
18+
@Input()
19+
get taxReturn(): HeroTaxReturn {
20+
return this.heroTaxReturnService.taxReturn;
21+
}
22+
set taxReturn (htr: HeroTaxReturn) {
23+
this.heroTaxReturnService.taxReturn = htr;
24+
}
25+
26+
constructor(private heroTaxReturnService: HeroTaxReturnService ) { }
27+
28+
onCanceled() {
29+
this.flashMessage('Canceled');
30+
this.heroTaxReturnService.restoreTaxReturn();
31+
};
32+
33+
onClose() { this.close.emit(); };
34+
35+
onSaved() {
36+
this.flashMessage('Saved');
37+
this.heroTaxReturnService.saveTaxReturn();
38+
}
39+
40+
flashMessage(msg: string) {
41+
this.message = msg;
42+
setTimeout(() => this.message = '', 500);
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// #docregion
2+
import { Injectable } from '@angular/core';
3+
import { HeroTaxReturn } from './hero';
4+
import { HeroesService } from './heroes.service';
5+
6+
@Injectable()
7+
export class HeroTaxReturnService {
8+
private currentTaxReturn: HeroTaxReturn;
9+
private originalTaxReturn: HeroTaxReturn;
10+
11+
constructor(private heroService: HeroesService) { }
12+
13+
set taxReturn (htr: HeroTaxReturn) {
14+
this.originalTaxReturn = htr;
15+
this.currentTaxReturn = htr.clone();
16+
}
17+
18+
get taxReturn (): HeroTaxReturn {
19+
return this.currentTaxReturn;
20+
}
21+
22+
restoreTaxReturn() {
23+
this.taxReturn = this.originalTaxReturn;
24+
}
25+
26+
saveTaxReturn() {
27+
this.taxReturn = this.currentTaxReturn;
28+
this.heroService.saveTaxReturn(this.currentTaxReturn).subscribe();
29+
}
30+
}

public/docs/_examples/hierarchical-dependency-injection/ts/app/hero.ts

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,31 @@
11
// #docregion
2+
23
export class Hero {
3-
id: number;
4-
name: string;
5-
power: string;
4+
id: number;
5+
name: string;
6+
tid: string; // tax id
7+
}
8+
9+
//// HeroTaxReturn ////
10+
let nextId = 100;
11+
12+
export class HeroTaxReturn {
13+
constructor(
14+
public id = nextId++,
15+
public hero: Hero,
16+
public income = 0 ) {
17+
if (id === 0) { id = nextId++; }
18+
}
19+
20+
get name() { return this.hero.name; }
21+
get tax() { return this.income ? .10 * this.income : 0; }
22+
get tid() { return this.hero.tid; }
23+
24+
toString() {
25+
return `${this.hero.name}`;
26+
}
27+
28+
clone() {
29+
return new HeroTaxReturn(this.id, this.hero, this.income);
30+
}
631
}
7-
// #enddocregion

0 commit comments

Comments
 (0)