我在单例配置服务中拥有google api密钥(一种在所有应用程序之间共享应用程序配置的方式)。
如何将apiKey变量传递给@NgModule中的模块?
`@NgModule({
进口:[
BrowserModule,
通用模块
FormsModule,
AgmCoreModule.forRoot({
apiKey:'YOUR_KEY'// <-我不能使用常量!!! 如何传递变量?
})
],
提供者:[],
声明:[AppComponent],
引导程序:[AppComponent]
})`
取决于您使用的是哪种构建工具(例如angular-cli或自定义webpack或...)以及变量的来源。
这可能有点棘手。 特别是当您还想使用AOT编译时,这会防止@NgModule
内部过多的动态代码。
我当前实现的解决方案是在我的主app.module中覆盖“惰性配置提供程序”。
在实际使用地图的模块中,我在forRoot中使用了一个空配置:
AgmCoreModule.forRoot()
在我的app.module.ts中:
导入注入令牌:
import { LAZY_MAPS_API_CONFIG }
from 'angular2-google-maps/core/services';
添加到@NgModule
:
providers: [
{provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
],
并实现该“ GoogleMapsConfig”类,该类应实现LazyMapsAPILoaderConfigLiteral
接口(来自“ angular2-google-maps / core / services”中的)。
@Injectable()
class GoogleMapsConfig {
apiKey: string;
...
constructor() {
apiKey = getMyApiKeyFromSomewhere()
...
}
}
在该可注入程序中,我可以注入其他服务并从某个位置读取配置。
(例如,如果您使用angular-cli,则可以在其中导入环境)。 或从浏览器中读取域...或调用服务器端API ...
我只是尝试以上。 它设法避免了AoT错误,但是API密钥没有传递给Google Maps-因此它会返回缺少密钥的错误。
在我的用例中,我使用Extended-define-webpack-plugin添加了编译时全局配置设置(可以根据构建类型等更改的API密钥)。
import { LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral } from 'angular2-google-maps/core/services';
@Injectable()
export class GoogleMapsConfig implements LazyMapsAPILoaderConfigLiteral {
apiKey: string = CONFIG.googleMapsAPIKey;
}
@NgModule({
declarations: [...],
imports: [...],
providers: [{provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}],
bootstrap: [AppComponent]
})
export class AppModule {}
并且,在我使用地图的延迟加载模块中,调用AgmCoreModule.forRoot()
我正在使用angular 4和CLI 1.0.2,我正在尝试通过@kyranjamie获得以上代码,但我无法vs.dev设置了不同的密钥
这是我的代码,我在做什么错?
`
@Injectable()
导出类GoogleMapsConfig实现LazyMapsAPILoaderConfigLiteral {
public apiKey:字符串;
Constructor(){
如果(environment.production){
this.apiKey =此处插入了密钥
};
}
}
@NgModule({
声明:[
AppComponent
],
进口:[
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
AppRoutingModule,
NgbModule.forRoot(),
NouisliderModule,
AgmCoreModule.forRoot()
],
提供者:[
{提供:LAZY_MAPS_API_CONFIG,useClass:GoogleMapsConfig}
],
引导程序:[AppComponent]
})
导出类AppModule {
}
`
您确定if (environment.production)
会解析为true吗?
我已经解决了这个问题,感谢您的反馈
@daBishMan或@kyranjamie ,如果你们弄清楚了,您可以发表最终解决方案吗? @kyranjamie ,我的问题似乎与您的问题类似,...在涉及AOT的产品上,在对maps.google.com的请求中对agm-map进行了初始化,...没有发送URL API-KEY参数。 因此,它会返回“缺少api密钥”错误。
@ jorrit-wehelp,谢谢您的指导。 我将下面列出的对我有用的内容包括在内。...
import {Injectable} from "@angular/core";
import {LazyMapsAPILoaderConfigLiteral} from "@agm/core";
import {Config} from "../providers/config";
@Injectable()
export class MapsConfig implements LazyMapsAPILoaderConfigLiteral{
public apiKey: string
public libraries: string[]
constructor(config: Config) {
this.apiKey = config.get("MAP_API_JS_KEY")
this.libraries = ['places']
console.log("lazy map init with " + this.apiKey)
}
}
在我的主要@ngmodule中,我在提供程序中有这个...
{
provide: LAZY_MAPS_API_CONFIG,
useClass: MapsConfig,
deps: [Config]
}
对Config类的引用是一个构建时Webpack变量替换,它设置了在Dev或Prod模式下使用的变量映射。
你好
我可以通过@ jorrit-wehelp注释来实现动态密钥,但是在我的情况下,用户注销并登录后,agmKey值未更新并且无法查看地图
我所做的就像在我们的模块组件中一样,我们添加了以下代码
所以我在地图@component
内部移动了class GoogleMapsConfig
和{provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
@component
``...
从'@ agm / core'导入{LAZY_MAPS_API_CONFIG,LazyMapsAPILoaderConfigLiteral};
从“ @ pl-core / _services”导入{AuthService};
@Injectable();
类GoogleMapsConfig实现LazyMapsAPILoaderConfigLiteral {
公共apiKey:字符串;
Constructor(){
console.log('INSIDE MAPs'); //这不会显示在控制台中
this.apiKey = _authService.currentUser()&& _authService.currentUser()。agmKey吗? _authService.currentUser()。agmKey:'';
_authService.getMapKey $ .subscribe((key)=> {
this.apiKey =键;
})
}
}
@成分({
选择器:“ map-comp”,
templateUrl:“ ./ dyn-map.component.html”,
styleUrls:['./dyn-map.component.scss'],
提供者:[{提供:LAZY_MAPS_API_CONFIG,useClass:GoogleMapsConfig}],
封装:ViewEncapsulation.None
})
```
在我们注销并与其他用户登录后,控件没有进入GoogleMapsConfig类内,该怎么办才能解决此问题?
我让@ jorrit-wehelp的解决方案正常工作,但只是间歇性地进行,因为我遇到了一种竞争情况,即我的返回api密钥的服务不会总是及时返回该密钥。
我的地图组件的构造函数:
constructor(private envService: EnvironmentService) {
this.envService.environment$.subscribe(environment => {
// setTimeout is to wait a beat since my GoogleMapsConfig receives
// the key at the same instant.
setTimeout(() => this.gmapsApiKeyReady = true);
});
}
然后在标记中:
<agm-map *ngIf="gmapsApiKeyReady" ...></agm-map>
我不知道这是否适用于每个人,或者是否更具体地视情况而定,但是我发现这是Angular的AOT编译过程的结果,而不是agm本身的问题。 这是我遇到的情况的概述。
我想使API密钥配置成为驱动,而不是硬编码字符串,这样在不同的环境中移动将允许我使用不同的API密钥并监视API的使用情况。 为了做到这一点,我让我的.NET后端将一些具有所需值的JavaScript注入到全局名称空间中,并存储在Example.Namespace.GoogleMapsApiKey
。 考虑到这一点,这是我的TypeScript代码。
// typings.d.ts
declare namespace Example.Namespace {
export const GoogleMapsApiKey: string;
}
// app.module.ts
import { AgmCoreModule } from "@agm/core";
import { NgModule } from "@angular/core";
@NgModule({
// ...
imports: [
AgmCoreModule.forRoot({
apiKey: Example.Namespace.GoogleMapsApiKey,
})
],
// ...
})
export class AppModule {}
我认为在AOT生成过程中会包含使用我需要的值为某些const全局变量创建类型定义。 但是,事实证明,AOT编译器仅支持TypeScript工具的子集,这阻止了在编译时将变量包括在内。 实际上,发生的是“仅初始化的变量和常量”错误,而没有从Angular CLI发出错误。 一旦我切换到使用通过类使用某种LAZY_MAPS_API_CONFIG
提供程序,我就能够成功。
由于此问题最近没有活动,因此已被自动标记为陈旧。 如果没有其他活动发生,它将关闭。 感谢你的贡献。
最有用的评论
取决于您使用的是哪种构建工具(例如angular-cli或自定义webpack或...)以及变量的来源。
这可能有点棘手。 特别是当您还想使用AOT编译时,这会防止
@NgModule
内部过多的动态代码。我当前实现的解决方案是在我的主app.module中覆盖“惰性配置提供程序”。
在实际使用地图的模块中,我在forRoot中使用了一个空配置:
在我的app.module.ts中:
导入注入令牌:
添加到
@NgModule
:并实现该“ GoogleMapsConfig”类,该类应实现
LazyMapsAPILoaderConfigLiteral
接口(来自“ angular2-google-maps / core / services”中的)。在该可注入程序中,我可以注入其他服务并从某个位置读取配置。
(例如,如果您使用angular-cli,则可以在其中导入环境)。 或从浏览器中读取域...或调用服务器端API ...