我使用angualr2-library yeoman generator创建了公司内部库。
一些角度服务在我们当前的应用程序中使用环境变量(api端点在每个env上都有变化)。我想知道将当前环境对象传递给angular2库服务的最佳方法是什么?
答案 0 :(得分:25)
如果你仍然在寻找解决方案,这就是我如何完成与你所要求的相似的东西(使用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 {
}
您LibraryModule
当然需要提供forRoot()
方法。
然后,在providers数组中,您可以提供值and more的服务。在这种情况下,为了简单起见,'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
}
]
};
}
}
由于您的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());
}
}
我希望有所帮助!
答案 1 :(得分:6)
我在a GitHub issue中找到了解决此问题的替代解决方案。 GitHub线程中的解决方案有一个错误(错字),因此我在此处包括了固定的解决方案:
首先,将一个提供程序添加到包含您的环境文件的顶级AppModule中。
import {environment} from '../environments/environment'
@NgModule({
providers: [
{provide: 'environment', useValue: environment}
]
// object properties omitted for brevity...
})
class AppModule {}
最后,利用Inject装饰器将环境文件包含在您希望的应用程序的任何其他部分中(库或其他):
@Component({
// object properties omitted for brevity
})
class MyComponent {
private environment
constructor(
@Inject('environment')
environment
) {
this.environment = environment
}
}
答案 2 :(得分:4)
使用 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 { }
<块引用>
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 }
]
};
}
}
<块引用>
configurations.ts(在“projects\library1\src\lib”文件夹中声明这个类)。声明您需要从“环境”文件中获取的所有配置。
export class Configurations {
public apiUrl: string;
constructor() {
this.apiUrl = '';
}
}
<块引用>
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;
}
}
<块引用>
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;
}
}
<块引用>
app.component.ts(使用 library1 组件确认 URL 已传递到您的库)。
.......
<lib-library1></lib-library1>
.......
答案 3 :(得分:0)
如果您仍在寻找答案。 在当前版本中,即Angular> 6,您无需执行任何操作。
angular-cli命令“ ng build --prod(用于生产)和ng build(用于开发)”将为您解决这个问题。
示例:如果要在开发环境中运行项目,则将从src / environments / environment.ts中捕获所有变量。 在您的组件库项目中,只需导入“从'environments / environment'导入{环境};“。 (请确保路径正确无误),这将取决于angle-cli build命令。
答案 4 :(得分:0)
我认为here的一种更好的方法
我认为你们会发现这很有用:将抽象类用作可交换行为的依赖注入标记
我在Nx项目中有3个Angular应用程序,它们共享一些常见的环境变量。公共站点,私有门户和管理应用程序。在我的库中,我使用的是抽象的Environment类,该类定义了常见的环境变量。
function clear_styles_and_scripts() {
global $wp_scripts;
global $wp_styles;
foreach( $wp_scripts->queue as $handle ) :
wp_dequeue_script( $handle );
wp_deregister_script( $handle );
endforeach;
foreach( $wp_styles ->queue as $handle ) :
wp_dequeue_style( $handle );
wp_deregister_style( $handle );
endforeach;
}
add_action( 'wp_enqueue_scripts', 'clear_styles_and_scripts', 100 );
然后我将3个environment.ts文件更改如下。
export abstract class Environment {
abstract readonly production: boolean;
abstract readonly appUrls: {
readonly public: string;
readonly portal: string;
readonly admin: string;
};
}
export const environment = new EnvironmentImpl(); 当然,environment.prod.ts与dev environment.ts是对称的。然后,在根目录app.module.ts中为每个Angular应用程序提供各自的环境依赖性。
import { Environment } from '@my-lib-prefix/common';
class EnvironmentImpl implements Environment {
production = false;
appUrls = {
public: 'http://localhost:4200',
portal: 'http://localhost:4201',
admin: 'http://localhost:4202'
};
}
现在,任何组件都可以以干净,通用的方式注入环境依赖项。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { Environment } from '@my-lib-prefix/common';
import { environment } from '../environments/environment';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [{ provide: Environment, useValue: environment }],
bootstrap: [AppComponent]
})
export class AppModule {}
它强制执行每个environment.ts以实现抽象类中定义的“公共”环境变量。此外,每个相应的EnvironmentImpl都可以使用针对应用的特定环境变量进行扩展。这种方法看起来非常灵活和干净。干杯! ^ _ ^
答案 5 :(得分:0)
如果您要为firebase传递环境变量,只需在您的库中使用它即可:
@NgModule({
declarations: [MyAngularComponent],
exports: [MyAngularComponent],
imports: [
AngularFireModule,
AngularFirestoreModule,
CommonModule
]
})
export class MyAngularModule {
public static forRoot(firebaseConfig: FirebaseOptions): ModuleWithProviders<MyAngularModule> {
return {
ngModule: MyAngularModule,
providers: [
{ provide: FIREBASE_OPTIONS, useValue: firebaseConfig }
]
}
}
}
然后将其导入,就像AngularFire ...
MyAngularModule.forRoot(environment.firebase)
来自此帖子:pass angularFire config imported in library using forRoot