angular-cn/aio/content/examples/testing/ts/plnkr.no-link.html

1160 lines
34 KiB
HTML

<html lang="en"><head></head><body><form id="mainForm" method="post" action="http://plnkr.co/edit/?p=preview" target="_self"><input type="hidden" name="files[styles.css]" value="/* Master Styles */
h1 {
color: #369;
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}
h2, h3 {
color: #444;
font-family: Arial, Helvetica, sans-serif;
font-weight: lighter;
}
body {
margin: 2em;
}
body, input[text], button {
color: #888;
font-family: Cambria, Georgia;
}
a {
cursor: pointer;
cursor: hand;
}
button {
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
button:disabled {
background-color: #eee;
color: #aaa;
cursor: auto;
}
/* Navigation link styles */
nav a {
padding: 5px 10px;
text-decoration: none;
margin-right: 10px;
margin-top: 10px;
display: inline-block;
background-color: #eee;
border-radius: 4px;
}
nav a:visited, a:link {
color: #607D8B;
}
nav a:hover {
color: #039be5;
background-color: #CFD8DC;
}
nav a.active {
color: #039be5;
}
/* items class */
.items {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 24em;
}
.items li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.items li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.items li.selected {
background-color: #CFD8DC;
color: white;
}
.items li.selected:hover {
background-color: #BBD8DC;
}
.items .text {
position: relative;
top: -3px;
}
.items .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
/* everywhere else */
* {
font-family: Arial, Helvetica, sans-serif;
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[systemjs.config.extras.js]" value="/** App specific SystemJS configuration */
System.config({
packages: {
// barrels
'app/model': {main:'index.js', defaultExtension:'js'},
'app/model/testing': {main:'index.js', defaultExtension:'js'}
}
});
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/banner.component.css]" value="h1 { color: green; font-size: 350%}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/dashboard/dashboard-hero.component.css]" value=".hero {
padding: 20px;
position: relative;
text-align: center;
color: #eee;
max-height: 120px;
min-width: 120px;
background-color: #607D8B;
border-radius: 2px;
}
.hero:hover {
background-color: #EEE;
cursor: pointer;
color: #607d8b;
}
@media (max-width: 600px) {
.hero {
font-size: 10px;
max-height: 75px; }
}
@media (max-width: 1024px) {
.hero {
min-width: 60px;
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/dashboard/dashboard.component.css]" value="[class*='col-'] {
float: left;
}
*, *:after, *:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
h3 {
text-align: center; margin-bottom: 0;
}
[class*='col-'] {
padding-right: 20px;
padding-bottom: 20px;
}
[class*='col-']:last-of-type {
padding-right: 0;
}
.grid {
margin: 0;
}
.col-1-4 {
width: 25%;
}
.grid-pad {
padding: 10px 0;
}
.grid-pad > [class*='col-']:last-of-type {
padding-right: 20px;
}
@media (max-width: 1024px) {
.grid {
margin: 0;
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/hero/hero-detail.component.css]" value="label {
display: inline-block;
width: 3em;
margin: .5em 0;
color: #607D8B;
font-weight: bold;
}
input {
height: 2em;
font-size: 1em;
padding-left: .4em;
}
button {
margin-top: 20px;
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer; cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
button:disabled {
background-color: #eee;
color: #ccc;
cursor: auto;
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/hero/hero-list.component.css]" value=".selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 10em;
}
.heroes li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes .text {
position: relative;
top: -3px;
}
.heroes .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
button {
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/app.component.html]" value="<app-banner></app-banner>
<app-welcome></app-welcome>
<nav>
<a routerLink=&quot;/dashboard&quot;>Dashboard</a>
<a routerLink=&quot;/heroes&quot;>Heroes</a>
<a routerLink=&quot;/about&quot;>About</a>
</nav>
<router-outlet></router-outlet>
<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[app/banner.component.html]" value="<h1>{{title}}</h1>
<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[app/dashboard/dashboard-hero.component.html]" value="<div (click)=&quot;click()&quot; class=&quot;hero&quot;>
{{hero.name | uppercase}}
</div>
<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[app/dashboard/dashboard.component.html]" value="<h2 highlight>{{title}}</h2>
<div class=&quot;grid grid-pad&quot;>
<dashboard-hero *ngFor=&quot;let hero of heroes&quot; class=&quot;col-1-4&quot;
[hero]=hero (selected)=&quot;gotoDetail($event)&quot; >
</dashboard-hero>
</div>
<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[app/hero/hero-detail.component.html]" value="<div *ngIf=&quot;hero&quot;>
<h2><span>{{hero.name | titlecase}}</span> Details</h2>
<div>
<label>id: </label>{{hero.id}}</div>
<div>
<label for=&quot;name&quot;>name: </label>
<input id=&quot;name&quot; [(ngModel)]=&quot;hero.name&quot; placeholder=&quot;name&quot; />
</div>
<button (click)=&quot;save()&quot;>Save</button>
<button (click)=&quot;cancel()&quot;>Cancel</button>
</div>
<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[app/hero/hero-list.component.html]" value="<h2 highlight=&quot;gold&quot;>My Heroes</h2>
<ul class=&quot;heroes&quot;>
<li *ngFor=&quot;let hero of heroes | async &quot;
[class.selected]=&quot;hero === selectedHero&quot;
(click)=&quot;onSelect(hero)&quot;>
<span class=&quot;badge&quot;>{{hero.id}}</span> {{hero.name}}
</li>
</ul>
<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[app/about.component.ts]" value="import { Component } from '@angular/core';
@Component({
template: `
<h2 highlight=&quot;skyblue&quot;>About</h2>
<twain-quote></twain-quote>
<p>All about this sample</p>`
})
export class AboutComponent { }
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/app-routing.module.ts]" value="import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { AboutComponent } from './about.component';
@NgModule({
imports: [
RouterModule.forRoot([
{ path: '', redirectTo: 'dashboard', pathMatch: 'full'},
{ path: 'about', component: AboutComponent },
{ path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule'}
])
],
exports: [ RouterModule ] // re-export the module declarations
})
export class AppRoutingModule { };
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/app.component.ts]" value="import { Component } from '@angular/core';
@Component({
moduleId: module.id,
selector: 'my-app',
templateUrl: './app.component.html'
})
export class AppComponent { }
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/app.module.ts]" value="import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { AboutComponent } from './about.component';
import { BannerComponent } from './banner.component';
import { HeroService,
UserService } from './model';
import { TwainService } from './shared/twain.service';
import { WelcomeComponent } from './welcome.component';
import { DashboardModule } from './dashboard/dashboard.module';
import { SharedModule } from './shared/shared.module';
@NgModule({
imports: [
BrowserModule,
DashboardModule,
AppRoutingModule,
SharedModule
],
providers: [ HeroService, TwainService, UserService ],
declarations: [ AppComponent, AboutComponent, BannerComponent, WelcomeComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/banner-inline.component.ts]" value="import { Component } from '@angular/core';
@Component({
selector: 'app-banner',
template: '<h1>{{title}}</h1>'
})
export class BannerComponent {
title = 'Test Tour of Heroes';
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/banner.component.ts]" value="import { Component } from '@angular/core';
@Component({
moduleId: module.id,
selector: 'app-banner',
templateUrl: './banner.component.html',
styleUrls: ['./banner.component.css']
})
export class BannerComponent {
title = 'Test Tour of Heroes';
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/dashboard/dashboard-hero.component.ts]" value="import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Hero } from '../model';
@Component({
moduleId: module.id,
selector: 'dashboard-hero',
templateUrl: './dashboard-hero.component.html',
styleUrls: [ './dashboard-hero.component.css' ]
})
export class DashboardHeroComponent {
@Input() hero: Hero;
@Output() selected = new EventEmitter<Hero>();
click() { this.selected.emit(this.hero); }
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/dashboard/dashboard.component.ts]" value="import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Hero, HeroService } from '../model';
@Component({
moduleId: module.id,
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: [ './dashboard.component.css' ]
})
export class DashboardComponent implements OnInit {
heroes: Hero[] = [];
constructor(
private router: Router,
private heroService: HeroService) {
}
ngOnInit() {
this.heroService.getHeroes()
.then(heroes => this.heroes = heroes.slice(1, 5));
}
gotoDetail(hero: Hero) {
let url = `/heroes/${hero.id}`;
this.router.navigateByUrl(url);
}
get title() {
let cnt = this.heroes.length;
return cnt === 0 ? 'No Heroes' :
cnt === 1 ? 'Top Hero' : `Top ${cnt} Heroes`;
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/dashboard/dashboard.module.ts]" value="import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { SharedModule } from '../shared/shared.module';
import { DashboardComponent } from './dashboard.component';
import { DashboardHeroComponent } from './dashboard-hero.component';
const routes: Routes = [
{ path: 'dashboard', component: DashboardComponent },
];
@NgModule({
imports: [
SharedModule,
RouterModule.forChild(routes)
],
declarations: [ DashboardComponent, DashboardHeroComponent ]
})
export class DashboardModule { }
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/hero/hero-detail.component.ts]" value="/* tslint:disable:member-ordering */
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import 'rxjs/add/operator/map';
import { Hero } from '../model';
import { HeroDetailService } from './hero-detail.service';
@Component({
moduleId: module.id,
selector: 'app-hero-detail',
templateUrl: './hero-detail.component.html',
styleUrls: ['./hero-detail.component.css' ],
providers: [ HeroDetailService ]
})
export class HeroDetailComponent implements OnInit {
constructor(
private heroDetailService: HeroDetailService,
private route: ActivatedRoute,
private router: Router) {
}
@Input() hero: Hero;
ngOnInit(): void {
// get hero when `id` param changes
this.route.params.map(p => p['id'])
.forEach(id => this.getHero(id))
.catch(() => this.hero = new Hero()); // no id; should edit new hero
}
private getHero(id: string): void {
this.heroDetailService.getHero(id).then(hero => {
if (hero) {
this.hero = hero;
} else {
this.gotoList(); // id not found; navigate to list
}
});
}
save(): void {
this.heroDetailService.saveHero(this.hero).then(() => this.gotoList());
}
cancel() { this.gotoList(); }
gotoList() {
this.router.navigate(['../'], {relativeTo: this.route});
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/hero/hero-detail.service.ts]" value="import { Injectable } from '@angular/core';
import { Hero, HeroService } from '../model';
@Injectable()
export class HeroDetailService {
constructor(private heroService: HeroService) { }
// Returns a clone which caller may modify safely
getHero(id: number | string): Promise<Hero> {
if (typeof id === 'string') {
id = parseInt(id as string, 10);
}
return this.heroService.getHero(id).then(hero => {
return hero ? Object.assign({}, hero) : null; // clone or null
});
}
saveHero(hero: Hero) {
return this.heroService.updateHero(hero);
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/hero/hero-list.component.ts]" value="import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Hero, HeroService } from '../model';
@Component({
moduleId: module.id,
selector: 'app-heroes',
templateUrl: './hero-list.component.html',
styleUrls: [ './hero-list.component.css' ]
})
export class HeroListComponent implements OnInit {
heroes: Promise<Hero[]>;
selectedHero: Hero;
constructor(
private router: Router,
private heroService: HeroService) { }
ngOnInit() {
this.heroes = this.heroService.getHeroes();
}
onSelect(hero: Hero) {
this.selectedHero = hero;
this.router.navigate(['../heroes', this.selectedHero.id ]);
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/hero/hero-routing.module.ts]" value="import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
const routes: Routes = [
{ path: '', component: HeroListComponent },
{ path: ':id', component: HeroDetailComponent }
];
export const routedComponents = [HeroDetailComponent, HeroListComponent];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class HeroRoutingModule {}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/hero/hero.module.ts]" value="import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module';
import { routedComponents, HeroRoutingModule } from './hero-routing.module';
@NgModule({
imports: [ SharedModule, HeroRoutingModule ],
declarations: [ routedComponents ]
})
export class HeroModule { }
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/model/hero.service.ts]" value="import { Injectable } from '@angular/core';
import { Hero } from './hero';
import { HEROES } from './test-heroes';
@Injectable()
/** Dummy HeroService. Pretend it makes real http requests */
export class HeroService {
getHeroes() {
return Promise.resolve(HEROES);
}
getHero(id: number | string): Promise<Hero> {
if (typeof id === 'string') {
id = parseInt(id as string, 10);
}
return this.getHeroes().then(
heroes => heroes.find(hero => hero.id === id)
);
}
updateHero(hero: Hero): Promise<Hero> {
return this.getHero(hero.id).then(h => {
if (!h) {
throw new Error(`Hero ${hero.id} not found`);
}
return Object.assign(h, hero);
});
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/model/hero.ts]" value="export class Hero {
constructor(public id = 0, public name = '') { }
clone() { return new Hero(this.id, this.name); }
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/model/http-hero.service.ts]" value="import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Headers, RequestOptions } from '@angular/http';
import { Hero } from './hero';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
@Injectable()
export class HttpHeroService {
private _heroesUrl = 'app/heroes'; // URL to web api
constructor (private http: Http) {}
getHeroes (): Observable<Hero[]> {
return this.http.get(this._heroesUrl)
.map(this.extractData)
// .do(data => console.log(data)) // eyeball results in the console
.catch(this.handleError);
}
getHero(id: number | string) {
return this.http
.get('app/heroes/?id=${id}')
.map((r: Response) => r.json().data as Hero[]);
}
addHero (name: string): Observable<Hero> {
let body = JSON.stringify({ name });
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this._heroesUrl, body, options)
.map(this.extractData)
.catch(this.handleError);
}
updateHero (hero: Hero): Observable<Hero> {
let body = JSON.stringify(hero);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.put(this._heroesUrl, body, options)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let body = res.json();
return body.data || { };
}
private handleError (error: any) {
// In a real world app, we might send the error to remote logging infrastructure
let errMsg = error.message || 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/model/index.ts]" value="// Model barrel
export * from './hero';
export * from './hero.service';
export * from './http-hero.service';
export * from './test-heroes';
export * from './user.service';
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/model/test-heroes.ts]" value="import { Hero } from './hero';
export var HEROES: Hero[] = [
new Hero(11, 'Mr. Nice'),
new Hero(12, 'Narco'),
new Hero(13, 'Bombasto'),
new Hero(14, 'Celeritas'),
new Hero(15, 'Magneta'),
new Hero(16, 'RubberMan')
];
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/model/testing/fake-hero.service.ts]" value="// re-export for tester convenience
export { Hero } from '../hero';
export { HeroService } from '../hero.service';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';
export var HEROES: Hero[] = [
new Hero(41, 'Bob'),
new Hero(42, 'Carol'),
new Hero(43, 'Ted'),
new Hero(44, 'Alice'),
new Hero(45, 'Speedy'),
new Hero(46, 'Stealthy')
];
export class FakeHeroService implements HeroService {
heroes = HEROES.map(h => h.clone());
lastPromise: Promise<any>; // remember so we can spy on promise calls
getHero(id: number | string) {
if (typeof id === 'string') {
id = parseInt(id as string, 10);
}
let hero = this.heroes.find(h => h.id === id);
return this.lastPromise = Promise.resolve(hero);
}
getHeroes() {
return this.lastPromise = Promise.resolve<Hero[]>(this.heroes);
}
updateHero(hero: Hero): Promise<Hero> {
return this.lastPromise = this.getHero(hero.id).then(h => {
return h ?
Object.assign(h, hero) :
Promise.reject(`Hero ${hero.id} not found`) as any as Promise<Hero>;
});
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/model/testing/index.ts]" value="export * from './fake-hero.service';
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/model/user.service.ts]" value="import { Injectable } from '@angular/core';
@Injectable()
export class UserService {
isLoggedIn = true;
user = {name: 'Sam Spade'};
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/shared/highlight.directive.ts]" value="import { Directive, ElementRef, Input, OnChanges } from '@angular/core';
@Directive({ selector: '[highlight]' })
/** Set backgroundColor for the attached element to highlight color
* and set the element's customProperty to true */
export class HighlightDirective implements OnChanges {
defaultColor = 'rgb(211, 211, 211)'; // lightgray
@Input('highlight') bgColor: string;
constructor(private el: ElementRef) {
el.nativeElement.style.customProperty = true;
}
ngOnChanges() {
this.el.nativeElement.style.backgroundColor = this.bgColor || this.defaultColor;
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/shared/shared.module.ts]" value="import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HighlightDirective } from './highlight.directive';
import { TitleCasePipe } from './title-case.pipe';
import { TwainComponent } from './twain.component';
@NgModule({
imports: [ CommonModule ],
exports: [ CommonModule, FormsModule,
HighlightDirective, TitleCasePipe, TwainComponent ],
declarations: [ HighlightDirective, TitleCasePipe, TwainComponent ]
})
export class SharedModule { }
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/shared/title-case.pipe.ts]" value="import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'titlecase', pure: false})
/** Transform to Title Case: uppercase the first letter of the words in a string.*/
export class TitleCasePipe implements PipeTransform {
transform(input: string): string {
return input.length === 0 ? '' :
input.replace(/\w\S*/g, (txt => txt[0].toUpperCase() + txt.substr(1).toLowerCase() ));
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/shared/twain.component.ts]" value="import { Component, OnInit } from '@angular/core';
import { TwainService } from './twain.service';
@Component({
selector: 'twain-quote',
template: '<p class=&quot;twain&quot;><i>{{quote}}</i></p>'
})
export class TwainComponent implements OnInit {
intervalId: number;
quote = '...';
constructor(private twainService: TwainService) { }
ngOnInit(): void {
this.twainService.getQuote().then(quote => this.quote = quote);
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/shared/twain.service.ts]" value="import { Injectable } from '@angular/core';
const quotes = [
'Always do right. This will gratify some people and astonish the rest.',
'I have never let my schooling interfere with my education.',
'Don\'t go around saying the world owes you a living. The world owes you nothing. It was here first.',
'Whenever you find yourself on the side of the majority, it is time to pause and reflect.',
'If you tell the truth, you don\'t have to remember anything.',
'Clothes make the man. Naked people have little or no influence on society.',
'It\'s not the size of the dog in the fight, it\'s the size of the fight in the dog.',
'Truth is stranger than fiction, but it is because Fiction is obliged to stick to possibilities; Truth isn\'t.',
'The man who does not read good books has no advantage over the man who cannot read them.',
'Get your facts first, and then you can distort them as much as you please.',
];
@Injectable()
export class TwainService {
private next = 0;
// Imaginary todo: get quotes from a remote quote service
// returns quote after delay simulating server latency
getQuote(): Promise<string> {
return new Promise(resolve => {
setTimeout( () => resolve(this.nextQuote()), 500 );
});
}
private nextQuote() {
if (this.next === quotes.length) { this.next = 0; }
return quotes[ this.next++ ];
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[app/welcome.component.ts]" value="import { Component, OnInit } from '@angular/core';
import { UserService } from './model';
@Component({
selector: 'app-welcome',
template: '<h3 class=&quot;welcome&quot; ><i>{{welcome}}</i></h3>'
})
export class WelcomeComponent implements OnInit {
welcome = '-- not initialized yet --';
constructor(private userService: UserService) { }
ngOnInit(): void {
this.welcome = this.userService.isLoggedIn ?
'Welcome, ' + this.userService.user.name :
'Please log in.';
}
}
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[main.ts]" value="// main app entry point
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[index.html]" value="<!-- Run the test app-->
<!DOCTYPE html>
<html>
<head>
<script>document.write('<base href=&quot;' + document.location + '&quot; />');</script>
<title>App Under Test</title>
<meta charset=&quot;UTF-8&quot;>
<meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;>
<link rel=&quot;stylesheet&quot; href=&quot;styles.css&quot;>
<!-- Polyfills -->
<script src=&quot;https://unpkg.com/core-js/client/shim.min.js&quot;></script>
<script src=&quot;https://unpkg.com/zone.js@0.7.4?main=browser&quot;></script>
<script src=&quot;https://unpkg.com/systemjs@0.19.39/dist/system.src.js&quot;></script>
<script src=&quot;https://cdn.rawgit.com/angular/angular.io/b3c65a9/public/docs/_examples/_boilerplate/systemjs.config.web.js&quot;></script>
<script src=&quot;systemjs.config.extras.js&quot;></script>
<script>
System.import('main.js').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>
<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="tags[0]" value="angular"><input type="hidden" name="tags[1]" value="example"><input type="hidden" name="tags[2]" value="testing"><input type="hidden" name="private" value="true"><input type="hidden" name="description" value="Angular Example - Heroes Test App"></form><script>document.getElementById("mainForm").submit();</script></body></html>