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


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 依赖注入学习系列的第四篇,主要介绍了Angular 4 依赖注入之FactoryProvider的使用,感兴趣的朋友们下面来看看详细的介绍:

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

  • Angular 4 +
  • Angular CLI
  • TypeScript

基础知识

FactoryProvider 的作用

FactoryProvider 用于告诉 Injector (注入器),通过调用 useFactory 对应的函数,返回 Token 对应的依赖对象。

FactoryProvider 的使用

function serviceFactory() { 
 return new Service();
}

const provider: FactoryProvider = {
 provide: 'someToken', useFactory: serviceFactory, deps: []
};

FactoryProvider 接口

export interface FactoryProvider {
 // 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、
 // OpaqueToken的实例或字符串
 provide: any;
 // 设置用于创建对象的工厂函数
 useFactory: Function;
 // 依赖对象列表
 deps?: any[];
 // 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖
 // 对象列表
 multi?: boolean;
}

FactoryProvider

介绍完基础知识,接下来我们马上进入正题。不知道大家是否还记得,之前我们创建过的 HeroComponent 组件:

import { Component, OnInit } from '@angular/core';
import { HeroService } from '../hero.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 {

 constructor(private heroService: HeroService) { }

 heros: Array<{ id: number; name: string }>;

 ngOnInit() {
 this.heros = this.heroService.getHeros();
 }
}

那么现在问题来了,假设我们想在获取英雄数据时,输出调试信息,那应该怎么办?What ~,这个问题不是很简单么,直接使用 console.log API 输出相应信息不就行了么:

console.log('Fetching heros...');
this.heros = this.heroService.getHeros();

那问题又来了,如果多个组件都使用 HeroService 去获取英雄数据,那么是不是每个组件都得添加对应的语句。另外如果要修改输出的调试信息,那就得修改程序中多个地方。其实我们一般只需要在开发阶段,输出调试信息,因此上面的方案不合理,也不够灵活。

其实我们可以借鉴之前引入 HeroService 服务的思路,创建一个 LoggerService 来解决上面提到的问题。

创建 LoggerService 服务

export class LoggerService {
 constructor(private enable: boolean) { }

 log(message: string) {
 if(this.enable) {
  console.log(`LoggerService: ${message}`);
 }
 }
}

配置 LoggerService 服务

@NgModule({
 ...
 providers: [
 HeroService,
 LoggerService
 ],
 bootstrap: [AppComponent]
})
export class AppModule { }

使用 LoggerService 服务

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.heros = this.heroService.getHeros();
 }
}

以上代码运行后会抛出以下异常信息:

Uncaught Error: Can't resolve all parameters for LoggerService: (?).

有的读者,眼睛一亮,可能是你在创建 LoggerService 服务时,忘记使用 @Injectable 装饰器了。哈哈,其实我是故意的,但我加上 @Injectable() 后,还是抛出了以下异常:

ERROR Error: No provider for Boolean!

为什么会出现上面的异常信息呢?我们再看一下前面创建的 LoggerService 服务:

export class LoggerService {
 constructor(private enable: boolean) { }
 // ...
}

在 Angular 中我们通过构造注入的方式注入依赖对象, private enable: boolean 这种方式表示我们要注入 Type 类型的对象。然后 boolean 是表示基本数据类型,并不是所需的 Type 类型:

export function isType(v: any): v is Type<any> {
 return typeof v === 'function';
}

接下来我们再来看一下最早抛出的异常:

Uncaught Error: Can't resolve all parameters for LoggerService: (?).

其实问题的答应也在 LoggerService 类的构造函数中,在创建 LoggerService 对象时,我们需要设置 enable 参数的值。那么如何解决呢? 当然可以使用我们的主角 - FactoryProvider 。

具体如下:

使用 FactoryProvider

@NgModule({
 ...,
 providers: [
 HeroService,
 {
 provide: LoggerService, 
 useFactory: () => {
 return new LoggerService(true);
 }
 }
 ],
 bootstrap: [AppComponent]
})
export class AppModule { }

当更新完代码,然后再来一个华丽的保存操作,最后打开你的控制台,你将看到预期的输出信息:

LoggerService: Fetching heros...

难道就这样结束了,关于 FactoryProvider 的相关内容先告一段落,下一篇我们将介绍如何使用 FactoryProvider 配置依赖对象。

总结

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

Javascript 相关文章推荐
捕获键盘事件(且兼容各浏览器)
Jul 03 Javascript
Knockout数组(observable)使用详解示例
Nov 15 Javascript
简单的ajax连接库分享(不用jquery的ajax)
Jan 19 Javascript
jQuery中prevUntil()方法用法实例
Jan 08 Javascript
avalon js实现仿google plus图片多张拖动排序附源码下载
Sep 24 Javascript
javascript模块化简单解析
Apr 07 Javascript
javascript中的后退和刷新实现方法
Nov 10 Javascript
JavaScript实现弹出广告功能
Mar 30 Javascript
ES5 ES6中Array对象去除重复项的方法总结
Apr 27 Javascript
mint-ui 时间插件使用及获取选择值的方法
Feb 09 Javascript
jQuery实现图片上传预览效果功能完整实例【测试可用】
May 28 jQuery
JavaScript中的this原理及6种常见使用场景详解
Feb 14 Javascript
Angular 4依赖注入学习教程之ClassProvider的使用(三)
Jun 04 #Javascript
Angular 4依赖注入学习教程之组件服务注入(二)
Jun 04 #Javascript
JavaScript箭头(arrow)函数详解
Jun 04 #Javascript
Angular 4依赖注入学习教程之简介(一)
Jun 04 #Javascript
angularJs中datatable实现代码
Jun 03 #Javascript
angularJS利用ng-repeat遍历二维数组的实例代码
Jun 03 #Javascript
详解JavaScript调用栈、尾递归和手动优化
Jun 03 #Javascript
You might like
咖啡语言
2021/03/03 咖啡文化
php随机抽奖实例分析
2015/03/04 PHP
什么是OneThink oneThink后台添加插件步骤
2016/04/13 PHP
yii 框架实现按天,月,年,自定义时间段统计数据的方法分析
2020/04/04 PHP
一个加密JavaScript的开源工具PACKER2.0.2
2006/11/04 Javascript
基于Jquery的表格隔行换色,移动换色,点击换色插件
2010/12/22 Javascript
js猜数字小游戏的简单实现代码
2013/07/02 Javascript
JS关闭窗口或JS关闭页面的几种代码分享
2013/10/25 Javascript
jquery实现平滑的二级下拉菜单效果
2015/08/26 Javascript
学习JavaScript设计模式之单例模式
2016/01/19 Javascript
ES6概念 ymbol.for()方法
2016/12/25 Javascript
Vue DevTools调试工具的使用
2017/12/05 Javascript
react-native-video实现视频全屏播放的方法
2018/03/19 Javascript
微信小程序实现跑马灯效果完整代码(附效果图)
2018/05/30 Javascript
JavaScript前后端JSON使用方法教程
2020/11/23 Javascript
[42:32]Secret vs Optic 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python语言技巧之三元运算符使用介绍
2013/03/04 Python
python实时分析日志的一个小脚本分享
2017/05/07 Python
Python2和Python3之间的str处理方式导致乱码的讲解
2019/01/03 Python
Python高级特性 切片 迭代解析
2019/08/23 Python
基于Pytorch SSD模型分析
2020/02/18 Python
解决python中0x80072ee2错误的方法
2020/07/19 Python
Node.js 和 Python之间该选择哪个?
2020/08/05 Python
通过css3动画和opacity透明度实现呼吸灯效果
2019/08/09 HTML / CSS
安德玛加拿大官网:Under Armour加拿大
2019/10/02 全球购物
俄罗斯三星品牌商店:Samsungstore
2020/04/05 全球购物
老师自我鉴定范文
2013/12/25 职场文书
中学生寄语大全
2014/04/03 职场文书
个人安全承诺书
2014/05/22 职场文书
2014年四风问题自我剖析材料
2014/09/15 职场文书
情侣之间的道歉短信
2015/05/12 职场文书
拯救大兵瑞恩观后感
2015/06/09 职场文书
诚信教育主题班会
2015/08/13 职场文书
vue+spring boot实现校验码功能
2021/05/27 Vue.js
Java服务调用RestTemplate与HttpClient的使用详解
2022/06/21 Java/Android
Zabbix对Kafka topic积压数据监控的解决方案
2022/07/07 Servers