シングルトン構成サービス(すべてのアプリケーション間でアプリ構成を共有する方法)にGoogleAPIキーがあります。
@NgModule内のモジュールにapiKey変数を渡すにはどうすればよいですか?
`@NgModule({
輸入:[
BrowserModule、
CommonModule、
FormsModule、
AgmCoreModule.forRoot({
apiKey: 'YOUR_KEY' // <-定数を使用できません!!! 変数を渡すにはどうすればよいですか?
})
]、
プロバイダー:[]、
宣言:[AppComponent]、
ブートストラップ:[AppComponent]
}) `
使用しているビルドツールの種類(angular-cliやカスタムwebpackなど)と変数の取得元によって異なります。
これは少し注意が必要です。 特に、AOTコンパイルも使用する場合は、 @NgModule
内の動的コードが多すぎるのを防ぎます。
私が現在実装しているソリューションは、メインのapp.moduleの「lazyconfigprovider」をオーバーライドすることです。
実際にマップを使用するモジュールでは、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マップに渡されていないため、キー欠落エラーが返されます。
私のユースケースでは、 extended-define-webpack-pluginを
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()
呼び出します
私はAngular4とCLI1.0.2を使用していますが、
これは私のコードです、私は何が間違っているのですか?
`
@Injectable()
エクスポートクラスGoogleMapsConfigはLazyMapsAPILoaderConfigLiteralを実装します{
public apiKey:文字列;
コンストラクター(){
if(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初期化... URLAPI-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コメントのように、動的キーを実現できましたが、ユーザーがログアウトしてloggedInした後のシナリオでは、agmKey値が更新されず、マップを表示できません。
私がしたことは、モジュールコンポーネントで次のコードを追加したようなものでした
そこで、 class GoogleMapsConfig
と{provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
をマップ内に移動しました@component
`` `.. ..
import {LAZY_MAPS_API_CONFIG、LazyMapsAPILoaderConfigLiteral} from '@ agm / core';
'@ pl-core / _services'から{AuthService}をインポートします。
@Injectable();
クラスGoogleMapsConfigはLazyMapsAPILoaderConfigLiteralを実装します{
public apiKey:string;
コンストラクター(){
console.log( 'INSIDE MAPs'); //これはコンソールに表示されません
this.apiKey = _authService.currentUser()&& _authService.currentUser()。agmKey? _authService.currentUser()。agmKey: '';
_authService.getMapKey $ .subscribe((key)=> {
this.apiKey = key;
})
}
}
@成分({
セレクター: 'map-comp'、
templateUrl: './ dyn-map.component.html'、
styleUrls:['./ dyn-map.component.scss']、
プロバイダー:[{provide: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>
これがすべての人に当てはまるのか、それともケースバイケースであるのかはわかりませんが、これはagm自体の問題ではなく、AngularのAOTコンパイルプロセスの結果であることがわかりました。 これが私が持っていた状況の概要です。
さまざまな環境を移動することでさまざまな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 {}
必要な値を使用してconstグローバル変数の型定義を作成すると、AOTビルドプロセス中に含まれると思いました。 ただし、AOTコンパイラはTypeScriptツールのサブセットのみを初期化された変数と定数のみ」エラーであり、AngularCLIからエラーが発生することはありませんでした。 クラスを使用してある種のLAZY_MAPS_API_CONFIG
プロバイダーを使用するように切り替えると、正常に実行できました。
この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。
最も参考になるコメント
使用しているビルドツールの種類(angular-cliやカスタムwebpackなど)と変数の取得元によって異なります。
これは少し注意が必要です。 特に、AOTコンパイルも使用する場合は、
@NgModule
内の動的コードが多すぎるのを防ぎます。私が現在実装しているソリューションは、メインのapp.moduleの「lazyconfigprovider」をオーバーライドすることです。
実際にマップを使用するモジュールでは、forRootで空の構成を使用します。
私のapp.module.ts:
インジェクショントークンをインポートします。
@NgModule
プロバイダーに追加:そして、その 'GoogleMapsConfig'クラスを実装します。これは
LazyMapsAPILoaderConfigLiteral
インターフェースを実装する必要があります( 'から' angular2-google-maps / core / services ')。そのインジェクタブルでは、他のサービスをインジェクトして、どこかから構成を読み取ることができます。
(たとえば、angular-cliを使用する場合は、そこに環境をインポートできます)。 または、ブラウザからドメインを読み取る...またはサーバーサイドAPIを呼び出す...