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

Commit 7668edd

Browse files
docs(rxjs): Added developer guide on Observables
1 parent aff39d2 commit 7668edd

29 files changed

+929
-0
lines changed
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use strict'; // necessary for es6 output in node
2+
3+
import { browser
4+
/*, element, by, ElementFinder*/
5+
} from 'protractor';
6+
7+
describe('RxJS', function () {
8+
9+
beforeAll(function () {
10+
browser.get('');
11+
});
12+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// #docplaster
2+
// #docregion
3+
import { NgModule } from '@angular/core';
4+
import { RouterModule, Routes } from '@angular/router';
5+
import { HomeComponent } from './home.component';
6+
import { HeroDetailComponent } from './hero-detail.component';
7+
import { HeroSearchComponent } from './hero-search.component';
8+
9+
const appRoutes: Routes = [
10+
{ path: '', component: HomeComponent },
11+
{ path: 'hero/search', component: HeroSearchComponent },
12+
{ path: 'hero/:id', component: HeroDetailComponent }
13+
];
14+
15+
@NgModule({
16+
imports: [RouterModule.forRoot(appRoutes)],
17+
exports: [RouterModule]
18+
})
19+
export class AppRoutingModule {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// #docplaster
2+
// #docregion
3+
import { Component } from '@angular/core';
4+
5+
@Component({
6+
selector: 'my-app',
7+
template: `
8+
<h1 class="title">RxJS in Angular</h1>
9+
10+
<router-outlet></router-outlet>
11+
<loading-component></loading-component>
12+
`
13+
})
14+
export class AppComponent {
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// #docregion
2+
import { NgModule } from '@angular/core';
3+
import { BrowserModule } from '@angular/platform-browser';
4+
import { HttpModule } from '@angular/http';
5+
import { ReactiveFormsModule } from '@angular/forms';
6+
7+
import { AppComponent } from './app.component';
8+
import { AppRoutingModule } from './app-routing.module';
9+
import { HomeComponent } from './home.component';
10+
import { HeroesReadyComponent } from './heroes-ready.component';
11+
import { CounterComponent } from './counter.component';
12+
import { FormFieldComponent } from './form-field.component';
13+
import { LoadingComponent } from './loading.component';
14+
import { HeroSearchComponent } from './hero-search.component';
15+
import { HeroDetailComponent } from './hero-detail.component';
16+
import { HeroListComponent } from './hero-list.component';
17+
18+
import { LoadingService } from './loading.service';
19+
import { HeroService } from './hero.service';
20+
21+
// Imports for loading & configuring the in-memory web api
22+
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
23+
import { InMemoryDataService } from './in-memory-data.service';
24+
25+
@NgModule({
26+
imports: [
27+
BrowserModule,
28+
HttpModule,
29+
AppRoutingModule,
30+
ReactiveFormsModule,
31+
InMemoryWebApiModule.forRoot(InMemoryDataService)
32+
],
33+
declarations: [
34+
AppComponent,
35+
HomeComponent,
36+
HeroesReadyComponent,
37+
CounterComponent,
38+
FormFieldComponent,
39+
LoadingComponent,
40+
HeroSearchComponent,
41+
HeroDetailComponent,
42+
HeroListComponent
43+
],
44+
providers: [
45+
HeroService,
46+
LoadingService
47+
],
48+
bootstrap: [ AppComponent ]
49+
})
50+
export class AppModule {
51+
}
52+
// #enddocregion
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// #docplaster
2+
// #docregion
3+
import { Component, OnInit, OnDestroy } from '@angular/core';
4+
import { Subject } from 'rxjs/Subject';
5+
import { Subscription } from 'rxjs/Subscription';
6+
7+
@Component({
8+
selector: 'counter-component',
9+
template: `
10+
<p>
11+
Hero Counter: {{ count }}
12+
13+
<button (click)="increment()">Increment</button>
14+
</p>
15+
`
16+
})
17+
export class CounterComponent implements OnInit, OnDestroy {
18+
count: number = 0;
19+
counter$ = new Subject();
20+
sub: Subscription;
21+
22+
ngOnInit() {
23+
this.sub = this.counter$.subscribe();
24+
}
25+
26+
increment() {
27+
this.counter$.next(this.count++);
28+
}
29+
30+
ngOnDestroy() {
31+
this.sub.unsubscribe();
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// #docplaster
2+
// #docregion
3+
import 'rxjs/add/operator/takeUntil';
4+
import { Component, OnInit, OnDestroy } from '@angular/core';
5+
import { Subject } from 'rxjs/Subject';
6+
7+
@Component({
8+
selector: 'counter-component',
9+
template: `
10+
<p>
11+
Counter: {{ count }}
12+
13+
<button (click)="increment()">Increment</button>
14+
</p>
15+
`
16+
})
17+
export class CounterComponent implements OnInit, OnDestroy {
18+
count: number = 0;
19+
counter$ = new Subject();
20+
destroy$: Subject<any> = new Subject();
21+
22+
ngOnInit() {
23+
this.counter$.takeUntil(this.destroy$).subscribe();
24+
}
25+
26+
increment() {
27+
this.counter$.next(this.count++);
28+
}
29+
30+
ngOnDestroy() {
31+
this.destroy$.next();
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Injectable } from '@angular/core';
2+
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
3+
4+
export interface Event {
5+
type: string;
6+
message: string;
7+
}
8+
9+
@Injectable()
10+
export class EventAggregatorService {
11+
_events: Event[];
12+
events$: BehaviorSubject<Event[]> = new BehaviorSubject<any>([]);
13+
14+
add(event: Event) {
15+
this._events.push(event);
16+
this.next();
17+
}
18+
19+
clear() {
20+
this._events = [];
21+
this.next();
22+
}
23+
24+
next() {
25+
this.events$.next(this._events);
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// #docplaster
2+
// #docregion
3+
import 'rxjs/add/observable/of';
4+
import 'rxjs/add/observable/fromEvent';
5+
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
6+
import { Observable } from 'rxjs/Observable';
7+
8+
@Component({
9+
selector: 'form-field-component',
10+
template: `
11+
<h3>Observable Form Field</h3>
12+
<p>
13+
<input type="text" #name>
14+
<span *ngIf="blurred$ | async">Blurred</span>
15+
</p>
16+
`
17+
})
18+
export class FormFieldComponent implements OnInit {
19+
@ViewChild('name', { read: ElementRef }) name: ElementRef;
20+
21+
blurred$: Observable<boolean>;
22+
23+
ngOnInit() {
24+
this.blurred$ = Observable.fromEvent(this.name.nativeElement, 'blur');
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// #docplaster
2+
// #docregion
3+
import 'rxjs/add/observable/of';
4+
import 'rxjs/add/operator/map';
5+
import 'rxjs/add/operator/do';
6+
import 'rxjs/add/operator/filter';
7+
import { Component, OnInit } from '@angular/core';
8+
import { ActivatedRoute, Params } from '@angular/router';
9+
import { HeroService } from './hero.service';
10+
import { Hero } from './hero';
11+
import { Observable } from 'rxjs/Observable';
12+
13+
@Component({
14+
template: `
15+
<div *ngIf="loading">
16+
Loading Hero...
17+
</div>
18+
<div *ngIf="loaded && hero">
19+
<h3>HEROES</h3>
20+
<div>
21+
<label>Id: </label>{{ hero.id }}
22+
</div>
23+
<div>
24+
<label>Name: </label>
25+
<input placeholder="name" [value]="hero.name"/>
26+
</div>
27+
</div>
28+
<div *ngIf="loaded && !hero">
29+
No hero found
30+
</div>
31+
`
32+
})
33+
export class HeroDetailComponent implements OnInit {
34+
hero: Hero;
35+
loading: boolean = true;
36+
loaded: boolean;
37+
38+
constructor(
39+
private heroService: HeroService,
40+
private route: ActivatedRoute
41+
) {}
42+
43+
ngOnInit() {
44+
this.route.params
45+
.do(() => {
46+
this.loading = true;
47+
this.loaded = false;
48+
})
49+
.switchMap((params: Params) =>
50+
this.heroService.getHero(params['id'])
51+
.catch(() => Observable.of(null))
52+
)
53+
.do(() => {
54+
this.loading = false;
55+
this.loaded = true;
56+
})
57+
.subscribe(hero => this.hero = hero);
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// #docplaster
2+
// #docregion
3+
import { Component, OnInit } from '@angular/core';
4+
5+
import { HeroService } from './hero.service';
6+
import { Hero } from './hero';
7+
8+
@Component({
9+
selector: 'hero-list',
10+
template: `
11+
<h2>HEROES</h2>
12+
<ul class="items">
13+
<li *ngFor="let hero of heroes">
14+
<span class="badge">{{ hero.id }}</span> {{ hero.name }}
15+
</li>
16+
</ul>
17+
`
18+
})
19+
export class HeroListComponent implements OnInit {
20+
heroes: Hero[];
21+
22+
constructor(
23+
private service: HeroService
24+
) {}
25+
26+
ngOnInit() {
27+
this.service.getHeroes()
28+
.subscribe(heroes => this.heroes = heroes);
29+
}
30+
}
31+
// #enddocregion
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// #docplaster
2+
// #docregion
3+
import { Component, OnInit } from '@angular/core';
4+
5+
import { HeroService } from './hero.service';
6+
import { Hero } from './hero';
7+
8+
@Component({
9+
selector: 'hero-list',
10+
template: `
11+
<h2>HEROES</h2>
12+
<ul class="items">
13+
<li *ngFor="let hero of heroes">
14+
<span class="badge">{{ hero.id }}</span> {{ hero.name }}
15+
</li>
16+
</ul>
17+
`
18+
})
19+
export class HeroListComponent implements OnInit {
20+
heroes: Hero[];
21+
22+
constructor(
23+
private service: HeroService
24+
) {}
25+
26+
ngOnInit() {
27+
this.service.getHeroes()
28+
.toPromise()
29+
.then(heroes => this.heroes = heroes);
30+
}
31+
}
32+
// #enddocregion
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* #docregion */
2+
.search-result{
3+
border-bottom: 1px solid gray;
4+
border-left: 1px solid gray;
5+
border-right: 1px solid gray;
6+
width:195px;
7+
height: 20px;
8+
padding: 5px;
9+
background-color: white;
10+
cursor: pointer;
11+
}
12+
13+
.search-box{
14+
width: 200px;
15+
height: 20px;
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!-- #docregion -->
2+
<div id="search-component">
3+
<h4>Hero Search</h4>
4+
<form [formGroup]="form">
5+
<input formControlName="searchTerms" class="search-box" />
6+
</form>
7+
<div>
8+
<div *ngFor="let hero of heroes | async" class="search-result">
9+
<a [routerLink]="['/hero', hero.id]">{{ hero.name }}</a>
10+
</div>
11+
</div>
12+
</div>

0 commit comments

Comments
 (0)