Angular-google-maps: 変数apiKeyを使用してモジュールを初期化する方法

作成日 2017年02月03日  ·  12コメント  ·  ソース: SebastianM/angular-google-maps

シングルトン構成サービス(すべてのアプリケーション間でアプリ構成を共有する方法)にGoogleAPIキーがあります。

@NgModule内のモジュールにapiKey変数を渡すにはどうすればよいですか?

`@NgModule({

輸入:[
BrowserModule、
CommonModule、
FormsModule、
AgmCoreModule.forRoot({
apiKey: 'YOUR_KEY' // <-定数を使用できません!!! 変数を渡すにはどうすればよいですか?
})
]、
プロバイダー:[]、
宣言:[AppComponent]、
ブートストラップ:[AppComponent]
}) `

stale discussion / question

最も参考になるコメント

使用しているビルドツールの種類(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を呼び出す...

全てのコメント12件

使用しているビルドツールの種類(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キーを返すサービスが必ずしも間に合うとは限らない競合状態があったため、断続的にしか機能しませんでした。試してレンダリングする要素。 強制するために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プロバイダーを使用するように切り替えると、正常に実行できました。

この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。

このページは役に立ちましたか?
0 / 5 - 0 評価