Skip to content
This repository was archived by the owner on Apr 1, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6788c30
変数を定義してcomponentに表示
ikepon Jan 15, 2017
6694c3f
Heroの情報をclassを使って定義
ikepon Jan 15, 2017
0d3757d
heroの詳細を表示
ikepon Jan 15, 2017
88d0d09
templateを読みやすく修正
ikepon Jan 15, 2017
ace801b
hero name をinputタグに修正
ikepon Jan 15, 2017
2e00de3
2way binding のためにforms module を読み込む
ikepon Jan 15, 2017
c91f415
2way bindingを実装
ikepon Jan 15, 2017
98f3913
Hero一覧のデータを定義
ikepon Jan 15, 2017
a081ecd
Hero一覧を表示
ikepon Jan 15, 2017
0eb21a5
Heroリストにスタイルを追加
ikepon Jan 15, 2017
332ec2a
Clickイベントをテンプレートに追加
ikepon Jan 15, 2017
cfc5935
Heroを選択するとその詳細が表示される
ikepon Jan 15, 2017
6071bf0
選択されたヒーローのスタイルを変える
ikepon Jan 15, 2017
ad2a0c0
ヒーロー詳細のテンプレートを作成
ikepon Jan 15, 2017
94fc326
Heroクラスの切り出し
ikepon Jan 15, 2017
4dc3eda
Hero詳細を表示できるようにhero と selectedHeroをbind
ikepon Jan 15, 2017
7e4f2d3
HeroServiceのベースを作成
ikepon Jan 16, 2017
6e8a278
HEROのデータモックを作成
ikepon Jan 16, 2017
9ae5642
Heros を読み込み、heroesパラメータにHeroクラスの配列を入れる
ikepon Jan 16, 2017
6d6eabc
HeroServiceでHero mock を返す
ikepon Jan 16, 2017
05287c0
Heroesをapp.componentから呼び出す
ikepon Jan 17, 2017
7e2538e
ngOnInit から getHeroesを呼び出し
ikepon Jan 17, 2017
d0b2191
app.componentからpromiseを使ってgetHeroesを呼び出し
ikepon Jan 17, 2017
fd0ba8d
app.component を heroes.componentにrename
ikepon Jan 22, 2017
5e742ec
新しくapp.componentを作り、heroes.component, HeroServiceなどを設定
ikepon Jan 22, 2017
e7c8346
/heroesへのrouteを設定
ikepon Jan 22, 2017
660ab61
DashboardComponentを定義
ikepon Jan 22, 2017
619af3c
/へのアクセスはdashboardにリダイレクト
ikepon Jan 22, 2017
e35a80e
Dashboardへのリンクを追加
ikepon Jan 22, 2017
c3a1dc9
Dashboard にtop heroesを表示
ikepon Jan 22, 2017
fc0a811
Hero詳細へのrouteを定義
ikepon Jan 22, 2017
81725a3
Hero詳細ページへのリンクとページ詳細を調整
ikepon Jan 22, 2017
1f49f40
Routingを別ファイル化
ikepon Jan 22, 2017
45ceedb
簡単なHero情報コンテンツを追加
ikepon Jan 22, 2017
863732d
heroes.componentのhtmlとcssを別ファイル化
ikepon Jan 22, 2017
39135e6
Hero一覧に詳細へのリンクを追加
ikepon Jan 22, 2017
a9a4b50
dashboardとhero-detailのスタイルを調整
ikepon Jan 22, 2017
c19c7f2
app.componentのスタイルを調整
ikepon Jan 22, 2017
c76e43f
バグを修正
ikepon Jan 22, 2017
d02f769
Heroデータをin memory から取得
ikepon Feb 4, 2017
90ac81b
Heroを更新
ikepon Feb 5, 2017
094d942
Heroを作成
ikepon Feb 5, 2017
1a4be95
Heroを削除
ikepon Feb 5, 2017
f45f990
Hero検索
ikepon Feb 5, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
import { HeroDetailComponent } from './hero-detail.component';

const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'detail/:id', component: HeroDetailComponent },
{ path: 'heroes', component: HeroesComponent }
];

@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})

export class AppRoutingModule {}
28 changes: 28 additions & 0 deletions app/app.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
h1 {
font-size: 1.2em;
color: #999;
margin-bottom: 0;
}
h2 {
font-size: 2em;
margin-top: 0;
padding-top: 0;
}
nav a {
padding: 5px 10px;
text-decoration: none;
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;
}
17 changes: 15 additions & 2 deletions app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import { Component } from '@angular/core';

@Component({
moduleId: module.id,
selector: 'my-app',
template: '<h1>My First Angular App</h1>'
template:`
<h1>{{title}}</h1>
<nav>
<a routerLink="/dashboard" routerLinkActive="active">Dashboard</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
`,
styleUrls: [ 'app.component.css' ]
})
export class AppComponent { }

export class AppComponent {
title = 'Tour of Heroes';
}
41 changes: 35 additions & 6 deletions app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,41 @@
import { NgModule } from '@angular/core';
// ブラウザで表示させるために必要
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroSearchComponent } from './hero-search.component'

import { HeroService } from './hero.service';

import { AppRoutingModule } from './app-routing.module';

import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service';


// AppComponent を読みこんでる
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
imports: [
BrowserModule,
FormsModule,
HttpModule,
InMemoryWebApiModule.forRoot(InMemoryDataService),
AppRoutingModule
],
declarations: [
AppComponent,
DashboardComponent,
HeroesComponent,
HeroSearchComponent,
HeroDetailComponent
],
providers: [
HeroService
],
bootstrap: [ AppComponent ]
})

export class AppModule { }
61 changes: 61 additions & 0 deletions app/dashboard.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
[class*='col-'] {
float: left;
padding-right: 20px;
padding-bottom: 20px;
}
[class*='col-']:last-of-type {
padding-right: 0;
}
a {
text-decoration: none;
}
*, *:after, *:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
h3 {
text-align: center; margin-bottom: 0;
}
h4 {
position: relative;
}
.grid {
margin: 0;
}
.col-1-4 {
width: 25%;
}
.module {
padding: 20px;
text-align: center;
color: #eee;
max-height: 120px;
min-width: 120px;
background-color: #607D8B;
border-radius: 2px;
}
.module:hover {
background-color: #EEE;
cursor: pointer;
color: #607d8b;
}
.grid-pad {
padding: 10px 0;
}
.grid-pad > [class*='col-']:last-of-type {
padding-right: 20px;
}
@media (max-width: 600px) {
.module {
font-size: 10px;
max-height: 75px; }
}
@media (max-width: 1024px) {
.grid {
margin: 0;
}
.module {
min-width: 60px;
}
}
9 changes: 9 additions & 0 deletions app/dashboard.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<h3>Top Heroes</h3>
<div class="grid grid-pad">
<a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" class="col-1-4">
<div class="module hero">
<h4>{{hero.name}}</h4>
</div>
</a>
</div>
<hero-search></hero-search>
22 changes: 22 additions & 0 deletions app/dashboard.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Component, OnInit } from '@angular/core';

import { Hero } from './hero';
import { HeroService } from './hero.service';

@Component({
moduleId: module.id,
selector: 'my-dashboard',
templateUrl: 'dashboard.component.html',
styleUrls: [ 'dashboard.component.css' ]
})

export class DashboardComponent {
heroes: Hero[] = [];

constructor(private heroService: HeroService) {}

ngOnInit(): void {
this.heroService.getHeroes()
.then(heroes => this.heroes = heroes.slice(1, 5));
}
}
29 changes: 29 additions & 0 deletions app/hero-detail.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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;
}
11 changes: 11 additions & 0 deletions app/hero-detail.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div *ngIf="hero">
<h2>{{hero.name}} details!</h2>
<div>
<label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
<button (click)="save()">Save</button>
<button (click)="goBack()">Back</button>
</div>
40 changes: 40 additions & 0 deletions app/hero-detail.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';

import 'rxjs/add/operator/switchMap';

import { Hero } from './hero';
import { HeroService } from './hero.service';

@Component({
moduleId: module.id,
selector: 'my-hero-detail',
templateUrl: 'hero-detail.component.html',
styleUrls: [ 'hero-detail.component.css' ]
})

export class HeroDetailComponent implements OnInit {
hero: Hero;

ngOnInit(): void {
this.route.params
.switchMap((params: Params) => this.heroService.getHero(+params['id']))
.subscribe(hero => this.hero = hero);
}

constructor(
private heroService: HeroService,
private route: ActivatedRoute,
private location: Location
) {}

save(): void {
this.heroService.update(this.hero)
.then(() => this.goBack());
}

goBack(): void {
this.location.back();
}
}
14 changes: 14 additions & 0 deletions app/hero-search.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.search-result{
border-bottom: 1px solid gray;
border-left: 1px solid gray;
border-right: 1px solid gray;
width:195px;
height: 20px;
padding: 5px;
background-color: white;
cursor: pointer;
}
#search-box{
width: 200px;
height: 20px;
}
8 changes: 8 additions & 0 deletions app/hero-search.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div id="search-component">
<h4>Hero Search</h4>
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" >
<div>
<div *ngFor="let hero of heroes | async" (click)="gotoDetail(hero)" class="search-result">
{{hero.name}}
</div>
</div>
58 changes: 58 additions & 0 deletions app/hero-search.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

// Observable class extensions
import 'rxjs/add/observable/of';

// Observable operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';

import { HeroSearchService } from './hero-search.service';
import { Hero } from './hero';

@Component({
moduleId: module.id,
selector: 'hero-search',
templateUrl: './hero-search.component.html',
styleUrls: [ './hero-search.component.css' ],
providers: [HeroSearchService]
})
export class HeroSearchComponent implements OnInit {
heroes: Observable<Hero[]>;
private searchTerms = new Subject<string>();

constructor(
private heroSearchService: HeroSearchService,
private router: Router) {}

// Push a search term into the observable stream.
search(term: string): void {
this.searchTerms.next(term);
}

ngOnInit(): void {
this.heroes = this.searchTerms
.debounceTime(300) // wait 300ms after each keystroke before considering the term
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time the term changes
// return the http search observable
? this.heroSearchService.search(term)
// or the observable of empty heroes if there was no search term
: Observable.of<Hero[]>([]))
.catch(error => {
// TODO: add real error handling
console.log(error);
return Observable.of<Hero[]>([]);
});
}

gotoDetail(hero: Hero): void {
let link = ['/detail', hero.id];
this.router.navigate(link);
}
}
17 changes: 17 additions & 0 deletions app/hero-search.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

import { Hero } from './hero';

@Injectable()
export class HeroSearchService {
constructor(private http: Http) {}

search(term: string): Observable<Hero[]> {
return this.http.get(`app/heroes/?name=${term}`)
.map(response => response.json().data as Hero[]);
}
}
Loading