将环境变量传递给angular2库

Dim*_*man 27 angular-cli angular

我使用angualr2-library yeoman generator创建了公司内部库.

一些角度服务在我们当前的应用程序中使用环境变量(在每个env上更改api端点).我想知道将当前环境对象传递给angular2库服务的最佳方法是什么?

psc*_*ild 37

如果您仍然在寻找解决方案,这就是我如何完成与您要求的相似的东西(使用Angular 4.2.4).

在您AppModule(或您要导入图书馆的地方),请forRoot()在您的网站上调用该方法LibraryModule.借助此功能,您可以将任何配置值传递给您的库,例如您的应用程序环境.

import {environment} from "../environments/environment";
...

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        ...
        LibraryModule.forRoot(environment)
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}
Run Code Online (Sandbox Code Playgroud)

LibraryModule当然需要提供这种forRoot()方法.在providers数组中,您可以提供服务,值.在这种情况下,'env'为简单起见,充当保存给定环境对象的令牌.您也可以使用InjectionToken.

@NgModule({
    ...
})
export class LibraryModule {

    public static forRoot(environment: any): ModuleWithProviders {

        return {
            ngModule: LibraryModule,
            providers: [
                ImageService,
                {
                    provide: 'env', // you can also use InjectionToken
                    useValue: environment
                }
            ]
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

由于令牌env现在由您提供LibraryModule,因此您可以将其注入其所有子服务或组件中.

@Injectable()
export class ImageService {

    constructor(private http: Http, @Inject('env') private env) {
    }

    load(): Observable<any> {
        // assume apiUrl exists in you app's environment:
        return this.http.get(`${this.env.apiUrl}/images`)
            .map(res => res.json());
    }

}
Run Code Online (Sandbox Code Playgroud)

我希望有所帮助!

  • @pschild 那么您将如何在 !environment.Production 这样的库中执行开发模块的条件加载?StoreDevtoolsModule.instrument() : [] (2认同)

ant*_*ant 11

我在GitHub问题中找到了解决此问题的替代解决方案。GitHub线程中的解决方案有一个错误(错字),因此我在此处包括了固定的解决方案:

首先,将一个提供程序添加到包含环境文件的顶级AppModule中。

import {environment} from '../environments/environment'

@NgModule({
  providers: [
    {provide: 'environment', useValue: environment}
  ]
  // object properties omitted for brevity...
})
class AppModule {}
Run Code Online (Sandbox Code Playgroud)

最后,利用Inject装饰器将环境文件包含在您希望的应用程序的任何其他部分中(库或其他):

@Component({
  // object properties omitted for brevity
})
class MyComponent {

  private environment

  constructor(
    @Inject('environment')
    environment
  ) {
    this.environment = environment
  }

}
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案对我来说效果最好,干净且最小。谢谢! (3认同)
  • 你成功了。好一个 (2认同)
  • 最好的解决方案应该是优雅而简单的。 (2认同)

Moh*_*man 7

使用 Angular 11 的完整工作解决方案。假设您生成了一个library1使用命令命名的库ng generate library library1

应用模块文件

// Your other imports ...
import { Library1Module } from 'library1';
import { environment } from 'src/environments/environment';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,

    // Pass the data you want to share with your library. Here we will pass 'apiUrl'. 
    Library1Module.forRoot({ apiUrl: environment.apiUrl }),

    AppRoutingModule
  ]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

library1.module.ts('Library1' 模块主文件):

import { ModuleWithProviders, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Configurations } from './configurations';
import { Library1Component } from './library1.component';

@NgModule({
  declarations: [Library1Component],
  imports: [CommonModule],
  exports: [Library1Component]
})
export class Library1Module {

  // Create this static method in the library module.
  public static forRoot(config: Configurations): ModuleWithProviders<Library1Module> {

    return {
      ngModule: Library1Module,
      providers: [
        { provide: Configurations, useValue: config }
      ]
    };
  }

}
Run Code Online (Sandbox Code Playgroud)

configuration.ts(在“projects\library1\src\lib”文件夹中声明这个类)。声明您需要从“环境”文件中获取的所有配置。

export class Configurations {
  public apiUrl: string;

  constructor() {
    this.apiUrl = '';
  }

}
Run Code Online (Sandbox Code Playgroud)

library1.service.ts('Library1Service' 将接收配置对象)。

import { Injectable, Optional } from '@angular/core';
import { Configurations } from './configurations';

@Injectable({
  providedIn: 'root'
})
export class Library1Service {

  private _apiUrl = 'No value';

  constructor(@Optional() config?: Configurations) {
    if (config) {
      this._apiUrl = config.apiUrl;
    }
  }

  get apiUrl() {
    return this._apiUrl;
  }

}
Run Code Online (Sandbox Code Playgroud)

library1.component.ts(使用配置数据的Library1组件)。

import { Component } from '@angular/core';
import { Library1Service } from '../public-api';

@Component({
  selector: 'lib-library1',
  template: `
    <p>
      This component inside "library1" library and reads the values from "environment.ts" file.
    </p>

    <h1>API URL : {{apiUrl}}</h1>`
})
export class Library1Component {
  apiUrl = '';

  constructor(library1Service: Library1Service) {
    this.apiUrl = library1Service.apiUrl;
  }
}
Run Code Online (Sandbox Code Playgroud)

app.component.ts(确认 URL 已通过使用 library1 组件传递到您的库)。

.......
<lib-library1></lib-library1>
.......
Run Code Online (Sandbox Code Playgroud)