我正在构建一个应用程序,让你编辑地图,编辑器有带Agm地图模块的谷歌地图,用户的最终结果是一个带有地图的iframe嵌入到他的网页中。我将模块用于编辑器,并在app.module.ts中使用我的API键导入它。
import { AgmCoreModule } from '@agm/core';
...
imports: [
...
AgmCoreModule.forRoot({
apiKey: 'YOUR_KEY'
})
]
iframe将是一个单独的angular应用程序,使用相同的后端。我需要从数据库中提取用户的API密钥,但我不知道如何在Angular中构建这个部分,似乎它使用API密钥创建了构建,是否可以在运行时修改密钥?我在jQuery中看到过它。它可以从script标记中的代码中提取,或者在vanilla-js中提取,例如:
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
在最后一个例子中,它可以很容易地完成,谢谢
我直接解决了它,在我的情况下,我从API获得了密钥,代码为
import { AgmCoreModule, LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral }
from '@agm/core';
export function agmConfigFactory(http: HttpClient, config: LazyMapsAPILoaderConfigLiteral) {
const id = window.location.pathname.replace(///g, "");
return () => http.get<any>(`${environment.baseUrl}/map-display/${id}`).pipe(
map(response => {
config.apiKey = response.key;
return response;
})
).toPromise();
}
api调用的内容和id可以用所需的密钥替换。
import { AgmCoreModule, LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral }
from '@agm/core';
@Injectable()
export class GoogleMapsConfig implements LazyMapsAPILoaderConfigLiteral {
apiKey: string = CONFIG.googleMapsAPIKey;
}
您必须在@NgModule中的providers数组中添加一个指定函数的provider,在我的例子中是:
providers: [
{
provide: APP_INITIALIZER,
useFactory: agmConfigFactory,
deps: [HttpClient, LAZY_MAPS_API_CONFIG],
multi: true
}
],
对于我展示的一般示例,您可以使用Class而不是useFactory。你仍然需要在@NgModule的导入数组中提供一个初始密钥,它可能是一个无意义的字符串
AgmCoreModule.forRoot({ apiKey: "initialKey"}),
添加到上面的答案,添加下面的答案,使自动完成工作
AgmCoreModule.forRoot({
apiKey: 'initialKey',
language: 'en',
libraries: ['places']
}),
AppModule.ts文件
import {APP_INITIALIZER} from '@angular/core';
import { LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral } from '@agm/core';
import { GoogleMapsInitializer } from './shared/services/googleMapsInitializer';
imports: [
AgmCoreModule.forRoot({
apiKey: '',// this should be empty
libraries: ['places']
})
],
providers: [
{
// APP_INITIALIZER is the Angular dependency injection token.
provide: APP_INITIALIZER,
// Pass in the AGM dependency injection token.
deps: [LAZY_MAPS_API_CONFIG, GoogleMapsInitializer],
// Allow for multiple startup injectors if needed.
multi: true,
// UseFactory provides Angular with the function to invoke.
useFactory: (config: LazyMapsAPILoaderConfigLiteral, initializer: GoogleMapsInitializer) => () => initializer.initialize(config),
}]
GoogleMapsInitializer服务
import { LazyMapsAPILoaderConfigLiteral } from '@agm/core';
import { GoogleMapsConfigService } from '../rest-services/googleMapsConfigService';
export class GoogleMapsInitializer {
constructor(private googleMapsConfigService: GoogleMapsConfigService) { }
async initialize(config: LazyMapsAPILoaderConfigLiteral): Promise<void> {
try {
const apiKey = await this.googleMapsConfigService.getGoogleMapsApiKey();
console.log("API KEY IN INITIALIZE SERVICE ==> ", apiKey)
config.apiKey = apiKey;
} catch (error) {
console.error('Error setting Google Maps API key:', error);
}
}
}
GoogleMapsConfigService服务
import { HttpClient } from '@angular/common/http';
export class GoogleMapsConfigService {
constructor(private http: HttpClient) {}
getGoogleMapsApiKey(): Promise<string> {
const API_KEY_ENDPOINT = 'your api goes here';// get api key of google maps from backend service
return this.http.post<any>(API_KEY_ENDPOINT, {}).toPromise()
.then(response => response.apikey as string) // Replace 'apiKey' with the actual property name returned by your backend API.
.catch(error => {
console.error('Error fetching Google Maps API key:', error);
return '';
});
}
}
在应用程序启动期间,AppModule中的app_INITIALIZER会触发GoogleMapsInitializer服务。GoogleMapsInitializer服务使用Google MapsConfig service获取Google Maps API密钥。一旦获得密钥,就会在AgmCoreModule的配置对象中动态设置。