升级到 Angular 5 和 HttpClient
升级到 Angular 5 和 HttpClient,因为 Http 在 NG5 中已被弃用
引言
如果您有基于 Angular 2 或 4 构建的应用程序,那么迁移到 2017 年 11 月 1 日发布的 Angular 5 (AEST +10 11 月 2 日) 是无缝的。您的应用程序将立即享受 Angular 5 的大多数优点。
HttpClient 是在 Angular 4.3 中引入的,根据 Angular 的 ChangeLog 在 "5.0.0 pentagonal-donut (2017-11-01)" 部分:
http: 弃用 @angular/http,转而使用 @angular/common/http (#18906) (72c7b6e)
当然,您现有的使用 Http 服务的代码库在 Angular 的后续几个版本中仍然可以正常工作,直到 Angular 团队决定删除 @angular/http。
如果您(团队)有一些时间进行维护/重构工作,那么现在可能是迁移到 HttpClient@angular/common/http 的时候了。
备注
- 如果您使用的是 Angular Material 2 Beta 12,您可能需要小心,如此处报告。 好消息是,Material2 5.0.0-rc0 cesium-cephalopod (2017-11-06) 修复了该问题,并且也使用了 HttpClient。
升级
步骤 0:更新 node_modules 中的 NG 模块
在 *package.json* 中,您应该具有以下或类似的内容
"dependencies": {
"@angular/animations": "^5.0.0",
"@angular/cdk": "^2.0.0-beta.12",
"@angular/common": "^5.0.0",
"@angular/compiler": "^5.0.0",
"@angular/compiler-cli": "^5.0.0",
"@angular/core": "^5.0.0",
"@angular/forms": "^5.0.0",
<s>"@angular/http": "^5.0.0",</s>
"@angular/platform-browser": "^5.0.0",
"@angular/platform-browser-dynamic": "^5.0.0",
"@angular/platform-server": "^5.0.0",
"@angular/router": "^5.0.0",
删除整个 *node_moodules* 文件夹,然后运行 npm install
。
请注意,Http 服务的包可能会被删除,但将其留在那里并没有害处。 此外,如果您有其他依赖于 Http 服务的第三方 NG2 组件,您可能仍然需要已弃用的 Http 服务与 HttpClient 服务共存,直到供应商提供升级。
备注
您可能有自己喜欢的更新方法,那就继续使用吧。
步骤 1:优化 systemjs.config.js
map: {
app: 'app',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic':
'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'@angular/animations': 'npm:@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js',
'@angular/platform-browser/animations':
'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/cdk': 'npm:@angular/cdk/bundles/cdk.umd.js',
'@angular/cdk/a11y': 'npm:@angular/cdk/bundles/cdk-a11y.umd.js',
'@angular/cdk/bidi': 'npm:@angular/cdk/bundles/cdk-bidi.umd.js',
'@angular/cdk/coercion': 'npm:@angular/cdk/bundles/cdk-coercion.umd.js',
'@angular/cdk/collections': 'npm:@angular/cdk/bundles/cdk-collections.umd.js',
'@angular/cdk/keycodes': 'npm:@angular/cdk/bundles/cdk-keycodes.umd.js',
'@angular/cdk/observers': 'npm:@angular/cdk/bundles/cdk-observers.umd.js',
'@angular/cdk/overlay': 'npm:@angular/cdk/bundles/cdk-overlay.umd.js',
'@angular/cdk/platform': 'npm:@angular/cdk/bundles/cdk-platform.umd.js',
'@angular/cdk/portal': 'npm:@angular/cdk/bundles/cdk-portal.umd.js',
'@angular/cdk/rxjs': 'npm:@angular/cdk/bundles/cdk-rxjs.umd.js',
'@angular/cdk/scrolling': 'npm:@angular/cdk/bundles/cdk-scrolling.umd.js',
'@angular/cdk/stepper': 'npm:@angular/cdk/bundles/cdk-stepper.umd.js',
'@angular/cdk/table': 'npm:@angular/cdk/bundles/cdk-table.umd.js',
'tslib': 'npm:tslib/tslib.js',
// other libraries
'rxjs': 'npm:rxjs',
//temp fix according to https://github.com/ReactiveX/rxjs/issues/2971
'rxjs/operators': 'npm:rxjs/operators/index.js'
特别是,添加 '@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js' 和 'tslib': 'npm:tslib/tslib.js',并选择性地删除 '@angular/http' 的映射。
步骤 2:将所有 Http 声明替换为 HttpClient
在每个 *xxx.module.ts* 中,
替换 1
替换
import { HttpModule, Http, ... } from '@angular/http'
用
import { HttpClientModule, HttpClient, ... } from '@angular/common/http'
在 @NgModule
的 imports 部分,将 HttpModule
替换为 HttpClientModule
。
提示
确保在每个 TS/JS 文件中搜索 from @angular/http
。 即使您的应用程序代码没有使用该 import,该 import 仍可能尝试下载 js lib,并在浏览器的控制台中给出一些奇怪的 404 错误。
替换 2
在带有 Http 服务的 Angular 4.3 中,您可能需要在 *app.module.ts* 的 providers 部分提供以下内容
{
provide: Http,
useFactory: httpFactory,
deps: [XHRBackend, RequestOptions]
},
在带有 HttpClient 服务的 Angular 5 中,不需要这样做。 因此,只需将其删除,而无需为 DI 显式提供 HttpClient。
替换 3
与 Http 相比,HttpClient 为应用程序编程提供了更高级别的抽象。
使用 Http,您的应用程序代码通常如下所示
http.get(this.baseUri + 'api/Entities'+id)
.map(response=> response.json())
.subscribe(
data=>{
....
},
error=>{
....
});
"data
" 的数据类型较弱。
使用 HttpClient,您的应用程序代码将如下所示
httpClient.get<Entity>(this.baseUri + 'api/Entities'+id)
.subscribe(
data=>{
....
},
error=>{
....
});
"data
" 的数据类型与 Observable<Entity>
强类型。
根据您如何反序列化 JSON 数据,您可能需要进行大量替换。
关注点
如果您一直在为您的 ASP.NET WebApi + Angular2 解决方案使用 WebApiClientGen,则无需执行替换步骤 3,因为自 Angular 2 以来,WebApiClientGen
已经支持这种应用程序代码,就像 HttpClient 自 Angular 4.3 以来支持的那样。
使用 Http 服务,生成的客户端 API 如下所示
@Injectable()
export class Entities {
constructor(@Inject('baseUri') private baseUri: string = location.protocol + '//' +
location.hostname + (location.port ? ':' + location.port : '') + '/', private http: Http){
}
/**
* Get a person
* so to know the person
* GET api/Entities/{id}
* @param {number} id unique id of that guy
* @return {DemoWebApi_DemoData_Client.Person} person in db
*/
getPerson(id: number): Observable<DemoWebApi_DemoData_Client.Person>{
return this.http.get(this.baseUri + 'api/Entities/'+id).map(response=> response.json());
}
应用程序代码如下所示
entitiesService.getPerson(1001)
.subscribe(
data=>
{ ....
},
error=>{ .
...
});
"data
" 的数据类型已经与 Observable<DemoWebApi_DemoData_Client.Person>
强类型。
使用 HttpClient 服务,WebApiClientGen v2.3 生成的客户端 API 如下所示
@Injectable()
export class Entities {
constructor(@Inject('baseUri') private baseUri: string = location.protocol + '//' +
location.hostname + (location.port ? ':' + location.port : '') + '/', private http: HttpClient){
}
/**
* Get a person
* so to know the person
* GET api/Entities/{id}
* @param {number} id unique id of that guy
* @return {DemoWebApi_DemoData_Client.Person} person in db
*/
getPerson(id: number): Observable<DemoWebApi_DemoData_Client.Person>{
return this.http.get<DemoWebApi_DemoData_Client.Person>(this.baseUri + 'api/Entities/'+id);
}
所以您的应用程序代码可以保持不变,因为接口 getPerson(id: number): Observable<DemoWebApi_DemoData_Client.Person>
保持不变。
有关使用 WebApiClientGen
for Angular2 的更多详细信息,请查看
如果您一直在使用 jQuery 和 WebApiClientGen 进行 Web 编程,您也可能欢迎更改为 HttpClient,因为在 为 jQuery 生成的客户端 API 代码中,辅助类也命名为“HttpClient”。 并且在编程 .NET 客户端中,过去几年中常见的辅助类是 System.Net.Http.HttpClient。 因此,您有 3 个 Web 客户端编程框架共享 HTTP 客户端辅助类的相同名称。