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


Posted in Javascript onJune 04, 2017

学习目录

  • 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能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
用htc组件制作windows选项卡
Jan 13 Javascript
Javascript 代码也可以变得优美的实现方法
Jun 22 Javascript
node.js WEB开发中图片验证码的实现方法
Jun 03 Javascript
JS+CSS实现的拖动分页效果实例
May 11 Javascript
jQuery简单实现tab选项卡切换效果
Jun 20 Javascript
强大Vue.js组件浅析
Sep 12 Javascript
实现单层json按照key字母顺序排序的示例
Dec 06 Javascript
jQuery创建及操作xml格式数据示例
May 26 jQuery
vue配置文件实现代理v2版本的方法
Jun 21 Javascript
JQuery常用简单动画操作方法回顾与总结
Dec 07 jQuery
解决vue无法侦听数组及对象属性的变化问题
Jul 17 Javascript
Node.js中的异步生成器与异步迭代详解
Jan 31 Javascript
Angular 4依赖注入学习教程之Injectable装饰器(六)
Jun 04 #Javascript
Angular 4依赖注入学习教程之FactoryProvider配置依赖对象(五)
Jun 04 #Javascript
JavaScript基础之this详解
Jun 04 #Javascript
Angular 4 依赖注入学习教程之FactoryProvider的使用(四)
Jun 04 #Javascript
Angular 4依赖注入学习教程之ClassProvider的使用(三)
Jun 04 #Javascript
Angular 4依赖注入学习教程之组件服务注入(二)
Jun 04 #Javascript
JavaScript箭头(arrow)函数详解
Jun 04 #Javascript
You might like
php中的注释、变量、数组、常量、函数应用介绍
2012/11/16 PHP
php 无限级分类,超级简单的无限级分类,支持输出树状图
2014/06/29 PHP
thinkphp3.2实现在线留言提交验证码功能
2017/07/19 PHP
js 解决“options为空或不是对象”
2008/12/22 Javascript
禁用页面部分JavaScript不是全部而是部分
2014/09/03 Javascript
基于zepto.js实现仿手机QQ空间的大图查看组件ImageView.js详解
2015/03/05 Javascript
javascript数组去重的六种方法汇总
2015/08/16 Javascript
js带前后翻页的图片切换效果代码分享
2015/09/08 Javascript
JavaScript Date对象详解
2016/03/01 Javascript
jquery表单插件Autotab使用方法详解
2016/06/24 Javascript
jQuery插件EasyUI实现Layout框架页面中弹出窗体到最顶层效果(穿越iframe)
2016/08/05 Javascript
原生的强大DOM选择器querySelector介绍
2016/12/21 Javascript
用jQuery旋转插件jqueryrotate制作转盘抽奖
2017/02/10 Javascript
对存在JavaScript隐式类型转换的四种情况的总结(必看篇)
2017/08/31 Javascript
webpack打包js文件及部署的实现方法
2017/12/18 Javascript
详解关于Angular4 ng-zorro使用过程中遇到的问题
2018/12/05 Javascript
javascript运行机制之执行顺序理解
2020/08/03 Javascript
在vue中使用jsonp进行跨域请求接口操作
2020/10/29 Javascript
python 禁止函数修改列表的实现方法
2017/08/03 Python
基于Python获取城市近7天天气预报
2019/11/26 Python
python给指定csv表格中的联系人群发邮件(带附件的邮件)
2019/12/31 Python
python如何使用腾讯云发送短信
2020/09/17 Python
苏宁红孩子母婴商城:redbaby
2017/02/12 全球购物
英国豪华家具和经典家居饰品购物网站:OKA
2020/06/05 全球购物
100%羊绒:NakedCashmere
2020/08/26 全球购物
《美丽的公鸡》教学反思
2014/02/25 职场文书
节水口号标语
2014/06/19 职场文书
欢迎标语大全
2014/06/21 职场文书
热情服务标语
2014/10/07 职场文书
机关职员工作检讨书
2014/10/23 职场文书
安全生产工作汇报
2014/10/28 职场文书
2014年技术部工作总结
2014/12/12 职场文书
初中体育教学随笔
2015/08/15 职场文书
2016入党积极分子党课培训心得体会
2016/01/06 职场文书
python异常中else的实例用法
2021/06/15 Python
分析mysql中一条SQL查询语句是如何执行的
2021/06/21 MySQL