学习目录

  • Angular 4 依赖注入教程之一 依赖注入简介
  • Angular 4 依赖注入教程之二 组件服务注入
  • Angular 4 依赖注入教程之三 ClassProvider的使用
  • Angular 4 依赖注入教程之四 FactoryProvider的使用
  • Angular 4 依赖注入教程之五 FactoryProvider配置依赖对象
  • Angular 4 依赖注入教程之六 Injectable 装饰器
  • Angular 4 依赖注入教程之七 ValueProvider的使用
  • Angular 4 依赖注入教程之八 InjectToken的使用

前言

本文主要给大家介绍了关于Angular 4依赖注入之ValueProvider使用的相关内容,分享出来供大家参考学习,下面来一起详细的介绍:

本系列教程的开发环境及开发语言:

  • Angular 4
  • Angular CLI
  • TypeScript

基础知识

ValueProvider 的作用

ValueProvider 用于告诉 Injector (注入器),但使用 Token 获取依赖对象时,则返回 useValue 指定的值。

ValueProvider 的使用

const provider: ValueProvider = {provide: 'someToken', useValue: 'someValue'};

ValueProvider 接口

export interface ValueProvider {
 // 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、
 // OpaqueToken的实例或字符串
 provide: any;
 // 设置注入的对象
 useValue: any;
 // 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖
 // 对象列表
 multi?: boolean;
}

json-server 简介

json-server 用于基于 JSON 数据快速地创建本地模拟的 REST API。

json-server 的安装

npm install -g json-server

json-server 的使用

json-server --watch db.json

Angular CLI 代理配置

创建 proxy.conf.json 文件

{
 "/heros": {
 "target": "http://localhost:3000",
 "secure": false
 }
}

更新 package.json 文件

{
 "scripts": {
 "start": "ng serve --proxy-config proxy.conf.json",
 }
}

ValueProvider

介绍完基础知识,我们马上进入正题。不知道大家是否还记得,在 "组件服务注入" 文章中提到的内容:

难道一切就这么结束了,No! No!别忘记了我们这节课的主题是介绍如何在组件中注入服务。在目前的 HeroComponent 组件,我们的英雄列表信息是固定的,在实际的开发场景中,一般需要从远程服务器获取相应的信息。

接下来我们将重构我们的 HeroService 服务,从 API 接口中获取英雄数据。要使用 Angular 的 Http 服务,首先需要在 AppModule 模块中导入 HttpModule ,然后在 HeroService 类的构造函数中注入 Http 服务。

更新 HeroService 服务

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';

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

import { LoggerService } from './logger.service';

@Injectable()
export class HeroService {
 constructor(private loggerService: LoggerService,
 private http: Http) { }

 apiUrl = 'http://localhost:4200/heros';

 getHeros(): Observable<Array<{ id: number; name: string }>> {
 this.loggerService.log('Fetching heros...');
 return this.http.get(this.apiUrl)
  .map(res => res.json())
 }
}

在 HeroService 服务中,我们通过注入 Http 服务对象的 get() 方法发送 HTTP 请求,从而从 API 接口中获取英雄的数据。

更新 HeroComponent 组件

import { Component, OnInit } from '@angular/core';
import { HeroService } from '../hero.service';
import { LoggerService } from '../logger.service';

@Component({
 selector: 'app-hero',
 template: `
 <ul>
 <li *ngFor="let hero of heros">
 ID: {{hero.id}} - Name: {{hero.name}}
 </li>
 </ul>
 `
})
export class HeroComponent implements OnInit {
 heros: Array<{ id: number; name: string }>;

 constructor(private heroService: HeroService,
 private loggerService: LoggerService) { }

 ngOnInit() {
 this.loggerService.log('Fetching heros...');
 this.heroService.getHeros()
 .subscribe(res => {
 this.heros = res;
 });
 }
}

更新完上述代码,成功保存后,你会发现 http://localhost:4200/ 页面,一片空白。这就对了,因为我们还没有启动本地的 json-server 服务器。接下来我们来配置并启动本地的 json-server 服务器:

创建 heros.json 文件

{
 "heros": [
 {"id":11,"name":"Mr. Nice"},
 {"id":12,"name":"Narco"},
 {"id":13,"name":"Bombasto"},
 {"id":14,"name":"Celeritas"},
 {"id":15,"name":"Magneta"}
 ]
}

启动 json-server 服务器

json-server --watch heros.json

当成功启动 json-server 服务器,在命令行中,你将看到以下输出信息:

\{^_^}/ hi!

Loading heros.json
Done

这表示本地 json-server 已经成功启动,此时重新刷新以下 http://localhost:4200/ 页面,你将看到以下信息:

ID: 11 - Name: Mr. Nice
ID: 12 - Name: Narco
ID: 13 - Name: Bombasto
ID: 14 - Name: Celeritas
ID: 15 - Name: Magneta

程序终于又正常运行了,但注意到 HeroService 服务中,我们通过以下方式定义 API 接口地址:

@Injectable()
export class HeroService {
 ...
 apiUrl = 'http://localhost:4200/heros';
}

这种方式有个问题,假设其它服务也要使用该地址,那么就得按照同样的方式去定义 API 接口地址。另外假设 API 接口地址需要更新,那就需要修改多个地方。针对上述问题,我们可以使用 ValueProvider 来解决问题。

使用 ValueProvider

@NgModule({
 ...,
 providers: [
 {
 provide: 'apiUrl',
 useValue: 'http://localhost:4200/heros'
 }
 ],
 bootstrap: [AppComponent]
})
export class AppModule { }

更新 HeroService 服务

@Injectable()
export class HeroService {
 constructor(private loggerService: LoggerService,
 private http: Http,
 @Inject('apiUrl') private apiUrl) { }

 getHeros(): Observable<Array<{ id: number; name: string }>> {
 this.loggerService.log('Fetching heros...');
 return this.http.get(this.apiUrl)
  .map(res => res.json())
 }
}

在 HeroService 类的构造函数中,我们通过 @Inject('apiUrl') 方式,注入 apiUrl 该 Token 对应的依赖对象,即 'http://localhost:4200/heros' 。为什么不能使用 private apiUrl: 'apiUrl' 的方式,希望读者好好回忆一下,之前我们介绍过的相关内容。

以上代码成功运行后,在 http://localhost:4200/ 页面,我们将看到预期的结果:

ID: 11 - Name: Mr. Nice
ID: 12 - Name: Narco
ID: 13 - Name: Bombasto
ID: 14 - Name: Celeritas
ID: 15 - Name: Magneta

我有话说

为什么在构造函数中,非 Type 类型的参数只能用 @Inject(Something) 的方式注入 ?
因为 Type 类型的对象,会被 TypeScript 编译器编译。即我们通过 class 关键字声明的服务,最终都会编译成 ES5 的函数对象。

在构造函数中,Type 类型的参数能用 @Inject(Type) 的方式注入么?

Type 类型的参数也能使用 @Inject(Type) 的方式注入,具体如下:

constructor(@Inject(Http) private http) { }

同样也可以使用以下方式:

constructor(@Inject(Http) private http: Http) { }

第一种方式虽然可以正常编译,但 IDE 会有如下的提示信息:

[ts] Parameter 'http' implicitly has an 'any' type.

第二种方式,虽然 Angular 内部会合并 design:paramtypes 与 parameters 内的 metadata 信息,但本人觉得是有点冗余了。 总而言之,若果是 Type 类型的参数,推荐使用下面的方式:

constructor(private http: Http) { }

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者使用Angular 4能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对Devmax的支持。

Angular 4依赖注入学习教程之ValueProvider的使用(七)的更多相关文章

  1. Angular 4依赖注入学习教程之ValueProvider的使用(七)

    这篇文章主要给大家介绍了关于Angular 4依赖注入之ValueProvider使用的相关资料,文中介绍的非常详细,对大家学习或者使用Angular4具有一定的参考学习价值,需要的朋友们下面来一起看看吧。

  2. 详解Angular4 路由设置相关

    本篇文章主要介绍了详解Angular4 路由设置相关,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. Angular4学习笔记router的简单使用

    本篇文章主要介绍了Angular4学习笔记router的简单使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. 详解在Angular4中使用ng2-baidu-map的方法

    这篇文章主要介绍了在Angular4中使用ng2-baidu-map的方法,本文分步骤给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

  5. angular4+百分比进度显示插件用法示例

    这篇文章主要介绍了angular4+百分比进度显示插件用法,结合实例形式分析了Angular4安装及使用百分比进度显示插件相关步骤与操作技巧,需要的朋友可以参考下

  6. PHP经典设计模式之依赖注入定义与用法详解

    这篇文章主要介绍了PHP经典设计模式之依赖注入,结合实例形式分析了php依赖注入的定义、原理与用法,需要的朋友可以参考下

  7. Angular4 中内置指令的基本用法

    不得不说指令是ng最为强大的功能之一,好吧,也可以去掉之一,是最强大的功能。下面这篇文章主要给大家介绍了关于Angular4中内置指令的基本用法,文中通过示例代码介绍的非常详细,需要的朋友们下面来一起看看吧。

  8. Vue privide 和inject 依赖注入的使用详解

    这篇文章主要介绍了Vue privide 和inject 依赖注入的用法,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. 对PHP依赖注入的理解实例分析

    这篇文章主要介绍了对PHP依赖注入的理解,结合实例形式详细分析了PHP依赖注入的相关概念与原理,需要的朋友可以参考下

  10. 对angular4子路由&amp;辅助路由详解

    今天小编就为大家分享一篇对angular4子路由&辅助路由详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部