Angular--用工厂方法或值对象来定义提供器
前言
上一篇博客介绍了注入器和提供器,同时也简单的讲解了一下控制反转,这篇博客是使用了工厂方法来定义提供器,所以可以过来了解一下。
内容
这个例子是在提供器方法的例子上建立的:
1.首先删除product2.component.ts
中的代码:
providers:[{
provide:ProductService,useClass:AnotherProductService
}]
最终效果:
import{Component,OnInit}from'@angular/core';
import{Product,ProductService}from'../shared/product.service';
import{AnotherProductService}from'../shared/another-product.service';
@Component({
selector:'app-product2',
templateUrl:'./product2.component.html',
styleUrls:['./product2.component.css']
})
exportclassProduct2ComponentimplementsOnInit{
product:Product;
constructor(privateproductService:ProductService){}
ngOnInit(){
this.product=this.productService.getProduct();
}
}
2.在app下的module中修改providers中的内容:
providers:[{
provide:ProductService,
useFactory:()=>{
constlogger=newLoggerService();
constdev=Math.random()>0.5;
if(dev){
returnnewProductService(logger);
}else{
returnnewAnotherProductService(logger);
}
}
},LoggerService],
最终结果:
import{BrowserModule}from'@angular/platform-browser';
import{NgModule}from'@angular/core';
import{FormsModule}from'@angular/forms';
import{HttpModule}from'@angular/http';
import{AppComponent}from'./app.component';
import{Product1Component}from'./product1/product1.component';
import{ProductService}from'./shared/product.service';
import{Product2Component}from'./product2/product2.component';
import{LoggerService}from'./shared/logger.service';
import{AnotherProductService}from'./shared/another-product.service';
@NgModule({
declarations:[
AppComponent,
Product1Component,
Product2Component
],
imports:[
BrowserModule,
FormsModule,
HttpModule
],
providers:[{
provide:ProductService,
useFactory:()=>{
constlogger=newLoggerService();
constdev=Math.random()>0.5;
if(dev){
returnnewProductService(logger);
}else{
returnnewAnotherProductService(logger);
}
}
},LoggerService],
bootstrap:[AppComponent]
})
exportclassAppModule{}
3.在another-product.service.ts
中修改
constructor(publiclogger:LoggerService){}
最终结果:
import{Injectable}from'@angular/core';
import{Product,ProductService}from'./product.service';
import{LoggerService}from'./logger.service';
@Injectable()
exportclassAnotherProductServiceimplementsProductService{
getProduct():Product{
returnnewProduct(1,'iphoneX',9999,'有刘海的苹果手机');
}
constructor(publiclogger:LoggerService){}
}
4.查看页面
刷新出来的效果是两款商品随机出现,但是模块中ProductService
中的对象是同一个,即同一次只出现一种效果,然后在现实生活中绝不可能出现这种现象,于是就需要引入声明
,修改@NgModule
中的内容。具体修改如下:
最终效果:
import{BrowserModule}from'@angular/platform-browser';
import{NgModule}from'@angular/core';
import{FormsModule}from'@angular/forms';
import{HttpModule}from'@angular/http';
import{AppComponent}from'./app.component';
import{Product1Component}from'./product1/product1.component';
import{ProductService}from'./shared/product.service';
import{Product2Component}from'./product2/product2.component';
import{LoggerService}from'./shared/logger.service';
import{AnotherProductService}from'./shared/another-product.service';
@NgModule({
declarations:[
AppComponent,
Product1Component,
Product2Component
],
imports:[
BrowserModule,
FormsModule,
HttpModule
],
providers:[{
provide:ProductService,
useFactory:(logger:LoggerService,appCongig)=>{
if(appConfig.isDev){
returnnewProductService(logger);
}else{
returnnewAnotherProductService(logger);
}
},
deps:[LoggerService,'APP_CONFIG']
},LoggerService,
{
provide:'APP_CONFIG',useVakye:{isDev:false}
}
],
bootstrap:[AppComponent]
})
exportclassAppModule{}
总结
在商品的这个组件里面在构造函数里面声明了ProductService的token来注入,Angular看到这个东西以后,就去找token所对应的注入器,然后在app.module.ts中找到了声明的ProductService,发现这个token是用工厂函数useFactory来进行实例化的,所以会调用工厂函数,在调用工厂函数的时候发现工厂函数又需要依赖另一个服务:LoggerService,然后LoggerService也是一个token,他需要一个LoggerService的提供器,然后Angular继续找LoggerService的提供器,根据LoggerService的提供器的声明来实例化一个LoggerService,如果LoggerService中也有一个工厂,那么Angular会继续找下去,直到最后找到了相应的内容生成ProductService的实例,在这个过程中,商品组件里面的ProductService根本就不需要知道如何去找寻,它只需要知道实例化好了的ProductService是什么就可以了,然后调取里面的方法。
end
谢谢您的阅读!
上一篇: Block中直接使用self,YTK中
下一篇: python 实现自动化