我们将用HTTPClient来添加一些数据持久化特效。
我们需要在App中启用HTTP服务,HttpClient是Angular通过http 与远程服务器通讯的机制。如果我们需要在整个App中使用并不需要重复导入。我们需要在AppModule顶层中从@angular/common/http 导入HttpClientModule 符号.
import { HttpClientModule } from ‘@angular/common/http‘
并在加入@NgModule.imports 数组中。我们将可以在其他的Services中使用。并不需要重复导入。
getHeroes(): Observable<object> { return this.http.get(‘http://localhost:8080/findByList/1‘,{ headers: new HttpHeaders().set(‘Access-Control-Allow-Origin‘,‘*‘) }); }
在使用http的时候我们可以看到HttpClient 带有很多调用方式,Get,Post,Postion,Put,Delete 等。我们可以选择合适的方式调用API,常用的Get , Post。
在我们获取数据的时候。我们可能会遇到一些跨域,或者需要发送认证给客户端以便通过服务器认证。我们可以把这些消息写进heades中。
由于远程服务器不会马上应答或者得到服务器的结果。那么我们在Component中。使用结果就会由于异步原因而获取不到结果。所以我们需要告诉返回Observable 模式告诉Component , 当获取到服务器返回结果之后再做处理。
getHeroes(): Observable<Hero[]> { return this.http.get<Hero[]>(‘http://localhost:8080/findByList/1‘,‘*‘) }); }
此方法会返回一个可广场的对象。只有再Component订阅此方法。方法才会执行,并在subscribe中处理返回结果。
//Component 中调用方式
this.heroesService.getHeroes() .subscribe(her => this.heroes = her);
当service没有返回数据或者不需要处理任何数据时。你只需要显示调subscribe即可
this.heroesService.getHeroes().subscribe();
可能有些人对Observable会感到陌生。RxJs也提供另一种方式Promise , 我们可以在 rxjs/operaters/toPromise中导入,并使用
getHeroes(): Promise<Hero[]> { return this.http.get(‘http://localhost:8080/findByList/1‘,‘*‘) }).toPromise().then((response) = > {
console.log(response);//输出response
}); }
当我们在Component中调用getHeroes() 方法我们就可以在then中处理返回结果。
当然任何程序都有可能出现各种问题。特别是从远程服务器获取数据的时候。我们的方法应该捕获数据并做适当的处理。
要捕获错误。我们需要使用RxJS的catchError() 操作符来简历对Observable或者Primise的处理管道pipe。
import { catchError,map,tap } from ‘rxjs/operators‘;
现在我们就可以使用pipe扩展Observable的结果。并给他一个catchError操作符。
getHeroes (): Observable<Hero[]> { return this.http.get<Hero[]>(this.heroesUrl) .pipe( catchError(this.handleError(‘getHeroes‘,[])) ); }
catchError() 操作符拦截失败的Observable,并把错误传给错误处理对象。所以我们把错误交给handleError。handleError(错误处理器)会处理这个错误。并返回一个无害的结果。以便应用能正常工作。
由于所有的HeroService方法都需要共享handleError方法。所以我们需要通用化错误处理器并且支持不同的需求。
/** * Handle Http operation that Failed. * Let the app continue. * @param operation - name of the operation that Failed * @param result - optional value to return as the observable result */ private handleError<T> (operation = ‘operation‘,result?: T) { return (error: any): Observable<T> => { // Todo: send the error to remote logging infrastructure console.error(error); // log to console instead // Todo: better job of transforming error for user consumption this.log(`${operation} Failed: ${error.message}`); // Let the app keep running by returning an empty result. return of(result as T); }; }
Service
的方法将会窥探 Observable
的数据流,并通过 log()
函数往页面底部发送一条消息。
它们可以使用 RxJS 的 tap
操作符来实现,该操作符会查看 Observable 中的值,使用那些值做一些事情,并且把它们传出来。 这种 tap
回调不会改变这些值本身。
/** GET heroes from the server */ getHeroes (): Observable<Hero[]> { return this.http.get<Hero[]>(this.heroesUrl) .pipe( tap(heroes => this.log(‘fetched heroes‘)),catchError(this.handleError(‘getHeroes‘,[])) ); }
AsyncPipe 如你所愿,*ngFor 重复渲染出了这些英雄。 仔细看,你会发现 *ngFor 是在一个名叫 heroes$ 的列表上迭代,而不是 heroes。
<li *ngFor="let hero of heroes$ | async" >
$ 是一个命名惯例,用来表明 heroes$ 是一个 Observable,而不是数组。 *ngFor 不能直接使用 Observable。 不过,它后面还有一个管道字符(|),后面紧跟着一个 async,它表示 Angular 的 AsyncPipe。 AsyncPipe 会自动订阅到 Observable,这样你就不用再在组件类中订阅了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。