如何在Angular 13中基于不同的环境(本地和qa)注入服务(本地和api)?

Posted

技术标签:

【中文标题】如何在Angular 13中基于不同的环境(本地和qa)注入服务(本地和api)?【英文标题】:How to inject services(local and api) based on different env's(local & qa) in Angular 13? 【发布时间】:2022-01-09 13:15:18 【问题描述】:

api-local.service.ts

import  Injectable  from '@angular/core';
import  HttpClient, HttpHeaders  from '@angular/common/http';
import  LoginRequest  from '../login/login-request';

@Injectable(
  providedIn: 'root'
)

export class ApiLocalService 

  constructor(private httpClient: HttpClient)  
  
  private headers = new HttpHeaders(
    'Content-Type': 'application/json; charset=utf-8',
    'Accept': 'application/json, text/plain'
  );

  userLoginLocal()
    console.log("inside LOCAL API service");
    return this.httpClient.get('../assets/data/login.json', headers:this.headers);
  

  getUserListLocal()
    return this.httpClient.get('../assets/data/userList.json' ,  headers: this.headers )
  

api.service.ts

import  Inject, Injectable  from '@angular/core';
import  HttpClient, HttpHeaders  from '@angular/common/http';
import  LoginRequest  from '../login/login-request';
import  EnvironmentConfig, ENV_CONFIG  from './environment-config.interface';

@Injectable(
  providedIn: 'root'
)

export class ApiService 

    public apiUrl: string;

  constructor(@Inject(ENV_CONFIG) config: EnvironmentConfig,private httpClient: HttpClient,) 
    this.apiUrl = `$config.environment.baseUrl`;
   
  
  private headers = new HttpHeaders(
    'Content-Type': 'application/json; charset=utf-8',
    'Accept': 'application/json, text/plain'
  );

  userLoginLocal()
    console.log("inside LOCAL API service");
    return this.httpClient.get('../assets/data/login.json', headers:this.headers);
  

  getUserListLocal()
    return this.httpClient.get('../assets/data/userList.json' ,  headers: this.headers )
  

auth-service.ts

import  EventEmitter, Injectable, Output  from '@angular/core';
import  Observable, throwError  from 'rxjs';
import  HttpClient  from '@angular/common/http';

import  LoginRequest  from '../login/login-request';
import  LoginResponse  from '../login/login-response';
import  LocalStorageService  from 'ngx-webstorage';
import  map, tap ,catchError from 'rxjs/operators';
import  environment  from 'src/environments/environment';

import  ApiLocalService  from './api-local.service';


@Injectable(
  providedIn: 'root'
)
export class AuthService 

  private API_URL = environment.API_URL;
  // private Local_Env = environment.Local_Env;
  private roles: Array<string> = [];

   
  @Output() loggedIn: EventEmitter<boolean> = new EventEmitter();
  @Output() username: EventEmitter<string> = new EventEmitter();
  @Output() admin: EventEmitter<boolean> = new EventEmitter();
  @Output() superAdmin: EventEmitter<boolean> = new EventEmitter();
  @Output() client: EventEmitter<boolean> = new EventEmitter();

  refreshTokenPayload = 
    refreshToken: this.getRefreshToken(),
    username: this.getUserName()
  
  constructor(private httpClient: HttpClient,private localStorage: LocalStorageService, 
              private apiLocalService:ApiLocalService)  

    
 
adminLogin(loginRequest: LoginRequest): Observable<boolean> 
  console.log("loginrequest:"+loginRequest);
  return this.httpClient.post<any>(this.API_URL+'/auth-service/login', loginRequest)
    .pipe(map(data => 
      console.log(data)
      if(data.roles.find((role: string) => role !='ROLE_SUPER_ADMIN' && role !='ROLE_ADMIN' && role !='ROLE_CLIENT'))
        return false;
      else
      this.localStorage.store('authenticationToken', data.authenticationToken);
    this.localStorage.store('username', data.username);
    this.localStorage.store('refreshToken', data.refreshToken);
    this.localStorage.store('expiresAt', data.expiresAt);
    this.localStorage.store('roles', JSON.stringify(data.roles));
    this.loggedIn.emit(true);
    this.username.emit(data.username);
    if(data.roles.find((role: string) => role =='ROLE_ADMIN'))
      this.admin.emit(true);
    
    if(data.roles.find((role: string) => role =='ROLE_SUPER_ADMIN'))
       this.superAdmin.emit(true);
    
    if(data.roles.find((role: string) => role =='ROLE_CLIENT'))
      this.client.emit(true);
   
    
    return true;
      
    ));
  

Auth-service 具有在“登录”组件中调用的 adminLogin。 我的要求是在 env=local 时调用 api-local.service.ts,否则在 env=qa 时调用 api.service.ts。 des 服务应该被注入到 adminLogin() 里面的 auth-service.ts 中。 快速帮助将不胜感激...

【问题讨论】:

【参考方案1】:

一个简单的解决方案可能是:

    创建一个接口,定义您的 2 个服务的方法:
export interface IApiService 

   userLoginLocal(): Observable<Add type here>;

   getUserListLocal(): Observable<Add type here>;


    让你的服务实现这个接口
...
export class ApiService implements IApiService 
   ....


export class ApiLocalService implements IApiService 
  ...

    将这两个服务注入到您的 AuthService 中:
export class AuthService 

    private apiService: IApiService;

    constructor(apiService: ApiService, apiLocalService: ApiLocalService) 
        if (environment.localEnv) 
           this.apiService = apiLocalService;
         else 
           this.apiService = apiService;
        
        // from here you can use this.apiService ....
    

【讨论】:

我应该为 observable 添加什么类型?既然 api-local 返回 d 本地 json 数据,而 api.service 返回 api 的数据? 你可以定义一个接口,匹配 json-File 中的数据或使用任何类型(不推荐,因为你失去了类型安全)。

以上是关于如何在Angular 13中基于不同的环境(本地和qa)注入服务(本地和api)?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Angular 2 为不同的环境加载不同的全局 css 样式

如何在 Angular 中为不同的环境设置配置或属性文件?

如何在 Angular2 中触发表单验证器

httprunner学习13-环境变量.env

从Angular中的不同本地主机获取数据

基于 Laravel 开发博客应用系列 —— 设置 Linux/Mac 本地开发环境