Angular 4 依赖注入学习教程之FactoryProvider的使用(四)
学习目录
- Angular4依赖注入教程之一依赖注入简介
- Angular4依赖注入教程之二组件服务注入
- Angular4依赖注入教程之三ClassProvider的使用
- Angular4依赖注入教程之四FactoryProvider的使用
- Angular4依赖注入教程之五FactoryProvider配置依赖对象
- Angular4依赖注入教程之六Injectable装饰器
- Angular4依赖注入教程之七ValueProvider的使用
- Angular4依赖注入教程之八InjectToken的使用
前言
本文属于Angular4依赖注入学习系列的第四篇,主要介绍了Angular4依赖注入之FactoryProvider的使用,感兴趣的朋友们下面来看看详细的介绍:
本系列教程的开发环境及开发语言:
- Angular4+
- AngularCLI
- TypeScript
基础知识
FactoryProvider的作用
FactoryProvider用于告诉Injector(注入器),通过调用useFactory对应的函数,返回Token对应的依赖对象。
FactoryProvider的使用
functionserviceFactory(){
returnnewService();
}
constprovider:FactoryProvider={
provide:'someToken',useFactory:serviceFactory,deps:[]
};
FactoryProvider接口
exportinterfaceFactoryProvider{
//用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、
//OpaqueToken的实例或字符串
provide:any;
//设置用于创建对象的工厂函数
useFactory:Function;
//依赖对象列表
deps?:any[];
//用于标识是否multipleproviders,若是multiple类型,则返回与Token关联的依赖
//对象列表
multi?:boolean;
}
FactoryProvider
介绍完基础知识,接下来我们马上进入正题。不知道大家是否还记得,之前我们创建过的HeroComponent组件:
import{Component,OnInit}from'@angular/core';
import{HeroService}from'../hero.service';
@Component({
selector:'app-hero',
template:`
- ID:{{hero.id}}-Name:{{hero.name}}
那么现在问题来了,假设我们想在获取英雄数据时,输出调试信息,那应该怎么办?What~,这个问题不是很简单么,直接使用console.logAPI输出相应信息不就行了么:
console.log('Fetchingheros...');
this.heros=this.heroService.getHeros();
那问题又来了,如果多个组件都使用HeroService去获取英雄数据,那么是不是每个组件都得添加对应的语句。另外如果要修改输出的调试信息,那就得修改程序中多个地方。其实我们一般只需要在开发阶段,输出调试信息,因此上面的方案不合理,也不够灵活。
其实我们可以借鉴之前引入HeroService服务的思路,创建一个LoggerService来解决上面提到的问题。
创建LoggerService服务
exportclassLoggerService{
constructor(privateenable:boolean){}
log(message:string){
if(this.enable){
console.log(`LoggerService:${message}`);
}
}
}
配置LoggerService服务
@NgModule({
...
providers:[
HeroService,
LoggerService
],
bootstrap:[AppComponent]
})
exportclassAppModule{}
使用LoggerService服务
import{Component,OnInit}from'@angular/core';
import{HeroService}from'../hero.service';
import{LoggerService}from'./../logger.service';
@Component({
selector:'app-hero',
template:`
- ID:{{hero.id}}-Name:{{hero.name}}
以上代码运行后会抛出以下异常信息:
UncaughtError:Can'tresolveallparametersforLoggerService:(?).
有的读者,眼睛一亮,可能是你在创建LoggerService服务时,忘记使用@Injectable装饰器了。哈哈,其实我是故意的,但我加上@Injectable()后,还是抛出了以下异常:
ERRORError:NoproviderforBoolean!
为什么会出现上面的异常信息呢?我们再看一下前面创建的LoggerService服务:
exportclassLoggerService{
constructor(privateenable:boolean){}
//...
}
在Angular中我们通过构造注入的方式注入依赖对象,privateenable:boolean这种方式表示我们要注入Type类型的对象。然后boolean是表示基本数据类型,并不是所需的Type类型:
exportfunctionisType(v:any):visType{ returntypeofv==='function'; }
接下来我们再来看一下最早抛出的异常:
UncaughtError:Can'tresolveallparametersforLoggerService:(?).
其实问题的答应也在LoggerService类的构造函数中,在创建LoggerService对象时,我们需要设置enable参数的值。那么如何解决呢?当然可以使用我们的主角-FactoryProvider。
具体如下:
使用FactoryProvider
@NgModule({
...,
providers:[
HeroService,
{
provide:LoggerService,
useFactory:()=>{
returnnewLoggerService(true);
}
}
],
bootstrap:[AppComponent]
})
exportclassAppModule{}
当更新完代码,然后再来一个华丽的保存操作,最后打开你的控制台,你将看到预期的输出信息:
LoggerService:Fetchingheros...
难道就这样结束了,关于FactoryProvider的相关内容先告一段落,下一篇我们将介绍如何使用FactoryProvider配置依赖对象。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者使用Angular4能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。