Передача переменных окружения в библиотеку angular2
Я создал внутреннюю библиотеку компании, используя генератор annomanr2-library yoman.
Некоторые из служб angular используют переменные среды в наших текущих приложениях (конечные точки api изменяются на каждом env). Мне было интересно, как лучше всего передать текущий объект среды в службы библиотеки angular2?
Ответы
Ответ 1
В случае, если вы все еще ищете решение, вот как я сделал что-то похожее на то, о чем вы просили (используя 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()
. В массиве поставщиков вы можете предоставлять услуги, значения и многое другое. В этом случае '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 environment:
return this.http.get('${this.env.apiUrl}/images')
.map(res => res.json());
}
}
Надеюсь, это поможет!
Ответ 2
Я нашел альтернативное решение этой проблемы в проблеме GitHub. Решение в потоке GitHub содержит ошибку (опечатку), поэтому я включаю фиксированное решение здесь:
Для начала добавьте провайдера в свой AppModule верхнего уровня, который содержит файл вашей среды.
import {environment} from '../environments/environment'
@NgModule({
providers: [
{provide: 'environment', useValue: environment}
]
// object properties omitted for brevity...
})
class AppModule {}
Наконец, используйте Inject decorator для включения файла среды в любую другую часть вашего приложения (библиотеку или иное):
@Component({
// object properties omitted for brevity
})
class MyComponent {
private environment
constructor(
@Inject('environment')
environment
) {
this.environment = environment
}
}
Ответ 3
There is a Better Way я Think from здесь
я думаю, что есть лучший способЯ подумал, что вы, ребята, сочтете это полезным: использование абстрактных классов в качестве маркеров внедрения зависимостей для заменяемого поведения
У меня есть 3 приложения Angular в проекте Nx, которые имеют общие переменные среды. Общедоступный сайт, частный портал и приложение администратора. В моих библиотеках я использую абстрактный класс Environment, который определяет общие переменные среды.
export abstract class Environment {
abstract readonly production: boolean;
abstract readonly appUrls: {
readonly public: string;
readonly portal: string;
readonly admin: string;
};
}
Затем я изменил 3 файла environment.ts следующим образом.
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'
};
}
export const environment = new EnvironmentImpl();
Environment.prod.ts, конечно, будет симметричен dev environment.ts. Затем я предоставляю соответствующую зависимость от среды в корневом каталоге app.module.ts для каждого приложения Angular.
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 {}
Теперь любой компонент может внедрять зависимости среды простым и понятным способом.
import { Component } from '@angular/core';
import { Environment } from '@my-lib-prefix/common';
@Component({
selector: 'my-login',
templateUrl: './my-login.component.html'
})
export class MyLoginComponent {
constructor(private env: Environment) {}
}
Он заставляет каждый environment.ts реализовывать "общие" переменные среды, определенные в абстрактном классе. Кроме того, каждый соответствующий EnvironmentImpl может быть расширен за счет собственных переменных среды, специфичных для приложения. Этот подход кажется очень гибким и чистым. Ура! ^ _ ^
Ответ 4
Если вы все еще ищете ответ. В текущей версии ie Angular> 6 вам не нужно ничего делать.
Команды angular-cli "ng build --prod (для Production) & ng build (для разработки)" позаботятся об этом для вас.
Пример. Если вы запускаете проект в среде разработки, все переменные захватываются из src/environment/environment.ts. В проекте библиотеки компонентов просто импортируйте "import {environment] из" среды/среды "; (пожалуйста, убедитесь в том, что путь) будет отслеживать среду в зависимости от команды сборки углового-cli.