angular4 官网英雄指南04

把服务和组件改为用 Angular 的 HTTP 服务实现
1、app.module.ts中导入HttpModule模块

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {FormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';

import { AppComponent } from './app.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';

import {HeroService} from './hero.service';
import { HeroesComponent } from './heroes/heroes.component';
import { DashboardComponent } from './dashboard/dashboard.component';

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

@NgModule({
  declarations: [
    AppComponent,
    HeroDetailComponent,
    HeroesComponent,
    DashboardComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AppRoutingModule
  ],
  providers: [HeroService],
  bootstrap: [AppComponent]
})
export class AppModule { }

2、模拟WebAPI
要使用 angular-in-memory-web-api 首先要 npm install


angular4 官网英雄指南04_第1张图片
Paste_Image.png

app.module.ts被修改成如下:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {FormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';

import { AppComponent } from './app.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';

import {HeroService} from './hero.service';
import { HeroesComponent } from './heroes/heroes.component';
import { DashboardComponent } from './dashboard/dashboard.component';

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

// Imports for loading & configuring the in-memory web api
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService }  from './in-memory-data.service';

@NgModule({
  declarations: [
    AppComponent,
    HeroDetailComponent,
    HeroesComponent,
    DashboardComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    //InMemoryWebApiModule将Http客户端默认的后端服务 — 这是一个辅助服务,负责与远程服务器对话 — 替换成了内存 Web API服务
    InMemoryWebApiModule.forRoot(InMemoryDataService),
    AppRoutingModule
  ],
  providers: [HeroService],
  bootstrap: [AppComponent]
})
export class AppModule { }

in-memory-data.service.ts

import { InMemoryDbService } from 'angular-in-memory-web-api';
export class InMemoryDataService implements InMemoryDbService {
  createDb() {
    let heroes = [
      {id: 11, name: 'Mr. Nice'},
      {id: 12, name: 'Narco'},
      {id: 13, name: 'Bombasto'},
      {id: 14, name: 'Celeritas'},
      {id: 15, name: 'Magneta'},
      {id: 16, name: 'RubberMan'},
      {id: 17, name: 'Dynama'},
      {id: 18, name: 'Dr IQ'},
      {id: 19, name: 'Magma'},
      {id: 20, name: 'Tornado'}
    ];
    return {heroes};
  }
}

修改hero.service.ts服务

import { Injectable } from '@angular/core';
import {Headers,Http} from '@angular/http';
import 'rxjs/add/operator/toPromise';

import {Hero} from './hero';
import {HEROES} from './mock-heroes';

@Injectable()
export class HeroService {
  private heroesUrl:string='api/heroes';   //URL to web api
  constructor(private http:Http){

  }
  getHero(id: number): Promise {
    //return this.getHeroes().then(heroes => heroes.find(hero => hero.id === id));
    const url = `${this.heroesUrl}/${id}`;
    return this.http.get(url)
      .toPromise()
      .then(response => response.json().data as Hero)
      .catch(this.handleError);
  }
  getHeroes():Promise{
    //return Promise.resolve(HEROES);
    return this.http.get(this.heroesUrl)
      .toPromise()
      .then(response=>response.json().data as Hero[])
      .catch(this.handleError);
  }
  getHeroesSlowly(): Promise {
    return new Promise(resolve => {
      // Simulate server latency with 2 second delay
      setTimeout(() => resolve(this.getHeroes()), 2000);
    });
  }
  private handleError(error:any):Promise{
    console.error('An error occurred',error);
    return Promise.reject(error.message||error);
  }
}

3、更新英雄详情
先在英雄详情模板的底部添加一个保存按钮,它绑定了一个click事件,事件绑定会调用组件中一个名叫save()的新方法:


//hero-detail.component.ts中添加保存方法
save(): void {
  this.heroService.update(this.hero)
    .then(() => this.goBack());
}

hero.service.ts修改

import { Injectable } from '@angular/core';
import {Headers,Http} from '@angular/http';
import 'rxjs/add/operator/toPromise';

import {Hero} from './hero';
import {HEROES} from './mock-heroes';

@Injectable()
export class HeroService {
  private heroesUrl:string='api/heroes';   //URL to web api
  private headers=new Headers({'Content-Type':'application/json'});
  constructor(private http:Http){

  }
  getHero(id: number): Promise {
    //return this.getHeroes().then(heroes => heroes.find(hero => hero.id === id));
    const url = `${this.heroesUrl}/${id}`;
    return this.http.get(url)
      .toPromise()
      .then(response => response.json().data as Hero)
      .catch(this.handleError);
  }
  getHeroes():Promise{
    //return Promise.resolve(HEROES);
    return this.http.get(this.heroesUrl)
      .toPromise()
      .then(response=>response.json().data as Hero[])
      .catch(this.handleError);
  }
  getHeroesSlowly(): Promise {
    return new Promise(resolve => {
      // Simulate server latency with 2 second delay
      setTimeout(() => resolve(this.getHeroes()), 2000);
    });
  }
  private handleError(error:any):Promise{
    console.error('An error occurred',error);
    return Promise.reject(error.message||error);
  }
  update(hero:Hero):Promise{
    const url=`${this.heroesUrl}/${hero.id}`;
    return this.http.put(url,JSON.stringify(hero),{headers:this.headers})
    .toPromise()
    .then(()=>hero)
    .catch(this.handleError);
  }
  create(name:string):Promise{
    return this.http
      .post(this.heroesUrl,JSON.stringify({name: name}), {headers: this.headers})
      .toPromise()
      .then(res=>res.json().data as Hero)
      .catch(this.handleError);
  }
  
  delete(id: number): Promise {
    const url = `${this.heroesUrl}/${id}`;
    return this.http.delete(url, {headers: this.headers})
      .toPromise()
      .then(() => null)
      .catch(this.handleError);
  }
}

heroes.component.ts修改

import { Component,OnInit } from '@angular/core';
import {Router} from '@angular/router';
import {Hero} from '../hero';
import {HeroDetailComponent} from '../hero-detail/hero-detail.component';
import {HeroService} from '../hero.service';

@Component({
  selector: 'my-heroes',
  template:`  
    
  • {{hero.id}} {{hero.name}}

{{selectedHero.name | uppercase}} is my hero

`, styleUrls:['./heroes.component.css'] }) export class HeroesComponent implements OnInit { heroes:Hero[]; selectedHero:Hero; constructor(private heroService:HeroService,private router:Router){ } onSelect(hero:Hero):void{ this.selectedHero=hero; } getHeroes():void{ this.heroService.getHeroes().then(heroes => this.heroes = heroes); } ngOnInit(){ this.getHeroes(); } gotoDetail(): void { this.router.navigate(['/detail', this.selectedHero.id]); } add(name:string):void{ name=name.trim(); if(!name) return; this.heroService.create(name) .then(hero=>{ this.heroes.push(hero); this.selectedHero=null; }); } delete(hero:Hero):void{ this.heroService .delete(hero.id) .then(() => { this.heroes = this.heroes.filter(h => h !== hero); if (this.selectedHero === hero) { this.selectedHero = null; } }); } }

4、为英雄指南添加英雄搜索
创建hero-search.service.ts服务 ng g service hero-search

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{
    return this.http.get(`app/heroes/?name=${term}`)
      .map(response=>response.json().data as Hero[]);
  }
}

再创建一个新的hero-search.component.ts组件
ng g component hero-search

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({
  selector: 'hero-search',
  templateUrl: './hero-search.component.html',
  styleUrls: [ './hero-search.component.css' ],
  providers: [HeroSearchService]
})
export class HeroSearchComponent implements OnInit {
  heroes: Observable;
  private searchTerms = new Subject();
  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([]))
      .catch(error => {
        // TODO: add real error handling
        console.log(error);
        return Observable.of([]);
      });
  }
  gotoDetail(hero: Hero): void {
    let link = ['/detail', hero.id];
    this.router.navigate(link);
  }
}

hero-search.component.html

Hero Search

{{hero.name}}

hero-search.component.css

.search-result{
  border-bottom: 1px solid gray;
  border-left: 1px solid gray;
  border-right: 1px solid gray;
  width:195px;
  height: 16px;
  padding: 5px;
  background-color: white;
  cursor: pointer;
}
.search-result:hover {
  color: #eee;
  background-color: #607D8B;
}
#search-box{
  width: 200px;
  height: 20px;
}

为仪表盘添加搜索组件
dashboard.component.html

Top Heroes

运行结果:


angular4 官网英雄指南04_第2张图片
Paste_Image.png

你可能感兴趣的:(angular4 官网英雄指南04)