1. 程式人生 > >Angular--用工廠方法或值物件來定義提供器

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

謝謝您的閱讀!