Angular-google-maps: wie man das Modul mit der Variablen apiKey initialisiert

Erstellt am 3. Feb. 2017  ·  12Kommentare  ·  Quelle: SebastianM/angular-google-maps

Ich habe den Google API-Schlüssel in einem Singleton-Konfigurationsdienst (eine Möglichkeit, die App-Konfiguration für die gesamte Anwendung freizugeben).

Wie kann ich der apiKey-Variablen das Modul in @NgModule übergeben?

`@NgModule ({

Importe: [
BrowserModule,
CommonModule,
FormsModule,
AgmCoreModule.forRoot ({
apiKey: 'YOUR_KEY' // <- Ich kann keine Konstante verwenden !!! Wie kann ich eine Variable übergeben?
})
],
Anbieter: [],
Deklarationen: [AppComponent],
Bootstrap: [AppComponent]
}) `

stale discussion / question

Hilfreichster Kommentar

Hängt davon ab, welche Art von Build-Tool Sie verwenden (z. B. Angular-Cli oder benutzerdefiniertes Webpack oder ...) und woher die Variable stammen soll.
Dies kann etwas schwierig sein. Insbesondere, wenn Sie auch die AOT-Kompilierung verwenden möchten, um zu viel dynamischen Code in @NgModule zu vermeiden.

Die Lösung, die ich derzeit implementiert habe, überschreibt den 'Lazy Config Provider' in meinem Hauptmodul app.module.

In dem Modul, in dem ich die Map tatsächlich verwende, verwende ich eine leere Konfiguration in forRoot:

AgmCoreModule.forRoot()

In meiner app.module.ts:
Importieren Sie das Injection-Token:

import { LAZY_MAPS_API_CONFIG }
  from 'angular2-google-maps/core/services';

Hinzufügen zu Anbietern in @NgModule :

providers: [
    {provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
  ],

Und implementieren Sie diese 'GoogleMapsConfig'-Klasse, die die LazyMapsAPILoaderConfigLiteral -Schnittstelle implementieren soll (von' von 'angle2-google-maps / core / services').

@Injectable()
class GoogleMapsConfig {
  apiKey: string;
...
  constructor() {
    apiKey = getMyApiKeyFromSomewhere()
...
  }
}

In diesem injizierbaren kann ich andere Dienste injizieren und die Konfiguration von irgendwoher lesen.
(zB wenn Sie angle-cli verwenden, können Sie dort Umgebungen importieren). Oder lesen Sie die Domain aus dem Browser aus ... oder rufen Sie eine serverseitige API auf ...

Alle 12 Kommentare

Hängt davon ab, welche Art von Build-Tool Sie verwenden (z. B. Angular-Cli oder benutzerdefiniertes Webpack oder ...) und woher die Variable stammen soll.
Dies kann etwas schwierig sein. Insbesondere, wenn Sie auch die AOT-Kompilierung verwenden möchten, um zu viel dynamischen Code in @NgModule zu vermeiden.

Die Lösung, die ich derzeit implementiert habe, überschreibt den 'Lazy Config Provider' in meinem Hauptmodul app.module.

In dem Modul, in dem ich die Map tatsächlich verwende, verwende ich eine leere Konfiguration in forRoot:

AgmCoreModule.forRoot()

In meiner app.module.ts:
Importieren Sie das Injection-Token:

import { LAZY_MAPS_API_CONFIG }
  from 'angular2-google-maps/core/services';

Hinzufügen zu Anbietern in @NgModule :

providers: [
    {provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
  ],

Und implementieren Sie diese 'GoogleMapsConfig'-Klasse, die die LazyMapsAPILoaderConfigLiteral -Schnittstelle implementieren soll (von' von 'angle2-google-maps / core / services').

@Injectable()
class GoogleMapsConfig {
  apiKey: string;
...
  constructor() {
    apiKey = getMyApiKeyFromSomewhere()
...
  }
}

In diesem injizierbaren kann ich andere Dienste injizieren und die Konfiguration von irgendwoher lesen.
(zB wenn Sie angle-cli verwenden, können Sie dort Umgebungen importieren). Oder lesen Sie die Domain aus dem Browser aus ... oder rufen Sie eine serverseitige API auf ...

Ich habe es gerade versucht. Es schafft es, AoT-Fehler zu umgehen, aber der API-Schlüssel wird nicht an Google Maps übergeben. Daher wird ein fehlender Schlüsselfehler zurückgegeben.

In meinem Anwendungsfall verwende ich das Extended-Define-Webpack-Plugin , um globale Konfigurationseinstellungen zur Kompilierungszeit hinzuzufügen (API-Schlüssel, die sich je nach Build-Typ usw. ändern können).

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 {}

Und in meinem faul geladenen Modul, in dem ich die Karte verwende, rufe ich AgmCoreModule.forRoot()

Ich verwende Angular 4 und CLI 1.0.2. Ich versuche, den obigen Code von @kyranjamie zu erhalten, aber ich kann dies nicht zum

Das ist mein Code. Was mache ich falsch?

`
@Injectable ()
Exportklasse GoogleMapsConfig implementiert LazyMapsAPILoaderConfigLiteral {
public apiKey: string;
Konstrukteur() {
if (environment.production) {
this.apiKey = SCHLÜSSEL HIER EINGEFÜGT
};
}}
}}
@NgModule ({
Erklärungen: [
AppComponent
],
Importe: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
AppRoutingModule,
NgbModule.forRoot (),
NouisliderModule,
AgmCoreModule.forRoot ()
],
Anbieter: [
{Geben Sie Folgendes an: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}
],
Bootstrap: [AppComponent]
})
Exportklasse AppModule {

}}
`

Sind Sie sicher, dass if (environment.production) jemals in true aufgelöst wird?

Ich habe dieses Problem gelöst, danke für Ihr Feedback

@daBishMan oder @kyranjamie , Wenn ihr das jemals herausgefunden könntet ihr eure endgültige Lösung veröffentlichen? @kyranjamie , mein Problem scheint

@ jorrit-wehelp, danke für deine Anleitung. Ich füge unten ein, was für mich funktioniert ....

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)
  }
}

In meinem Haupt- @ng-Modul habe ich dies in Anbietern ...

    {
      provide: LAZY_MAPS_API_CONFIG,
      useClass: MapsConfig,
      deps: [Config]
    }

Der Verweis auf die Config-Klasse ist ein Webpack-Variablen-Ersetzungszeitpunkt, der die Einstellungen einer Karte von Variablen ersetzt, die im Dev- oder Prod-Modus verwendet werden.

Hallo

Ich konnte den dynamischen Schlüssel erreichen, wie durch @ jorrit-wehelp-Kommentare, aber in meinem Szenario wird der agmKey-Wert nach dem Abmelden und Anmelden des Benutzers nicht aktualisiert und kann die Karte nicht sehen

Wie ich es gemacht habe, haben wir in unserer Modulkomponente den folgenden Code hinzugefügt
Also habe ich die class GoogleMapsConfig und {provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig} innerhalb der Karte @component verschoben

`` `...
{LAZY_MAPS_API_CONFIG, LazyMapsAPILoaderConfigLiteral} aus '@ agm / core' importieren;
{AuthService} aus '@ pl-core / _services' importieren;

@Injectable ();
Klasse GoogleMapsConfig implementiert LazyMapsAPILoaderConfigLiteral {
public apiKey: string;
Konstrukteur() {
console.log ('INSIDE MAPs'); // Dies wird in der Konsole nicht angezeigt
this.apiKey = _authService.currentUser () && _authService.currentUser (). agmKey? _authService.currentUser (). agmKey: '';
_authService.getMapKey $ .subscribe ((Schlüssel) => {
this.apiKey = key;
})
}}
}}

@Komponente({
Selektor: 'map-comp',
templateUrl: './dyn-map.component.html',
styleUrls: ['./dyn-map.component.scss'],
Anbieter: [{bereitstellen: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig}],
Kapselung: ViewEncapsulation.None
})

`` `
Nachdem wir uns abgemeldet und mit einem anderen Benutzer angemeldet haben, befindet sich das Steuerelement nicht in der GoogleMapsConfig-Klasse. Was kann ich tun, um dieses Problem zu lösen?

Ich hatte die Lösung von @ jorrit-wehelp, aber nur zeitweise, weil ich eine Race-Bedingung hatte, bei der mein Dienst, der den API-Schlüssel zurückgibt, ihn nicht immer rechtzeitig für den zurückgabElement zu versuchen und zu rendern. Um zu erzwingenUm zu warten, bis der API-Schlüssel zurückgegeben wurde, habe ich einfach Folgendes getan:

Konstruktor meiner Kartenkomponente:

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);
    });
  }

Dann im Markup:

<agm-map *ngIf="gmapsApiKeyReady" ...></agm-map>

Ich weiß nicht, ob dies für alle gilt oder ob dies eher von Fall zu Fall geschieht, aber ich habe festgestellt, dass dies das Ergebnis des AOT-Kompilierungsprozesses von Angular ist, im Gegensatz zu einem Problem mit agm selbst. Hier ist ein Überblick über die Situation, die ich hatte.

Ich wollte die API-Schlüsselkonfiguration anstelle einer fest codierten Zeichenfolge steuern, sodass ich beim Durchlaufen verschiedener Umgebungen verschiedene API-Schlüssel verwenden und die Verwendung der API überwachen kann. Zu diesem Zweck ließ ich mein .NET-Backend JavaScript mit dem Wert, den ich benötigte, in den globalen Namespace einfügen, der in Example.Namespace.GoogleMapsApiKey gespeichert war. In diesem Sinne war hier mein TypeScript-Code.

// 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 {}

Ich dachte, das Erstellen einer Typdefinition für eine konstante globale Variable mit dem von mir benötigten Wert würde während des AOT-Erstellungsprozesses einbezogen. Wie sich herausstellt, unterstützt der AOT-Compiler jedoch nur eine Teilmenge der TypeScript-Tools , wodurch verhindert wurde, dass die Variable zum Zeitpunkt der Kompilierung aufgenommen wird. Tatsächlich geschah ein Fehler " Nur initialisierte Variablen und Konstanten ", ohne dass ein Fehler von der Angular CLI ausgegeben wurde. Nachdem ich den Wechsel vorgenommen hatte, um eine Art LAZY_MAPS_API_CONFIG -Anbieter mit einer Klasse zu verwenden, konnte ich erfolgreich.

Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivitäten gab. Es wird geschlossen, wenn keine weitere Aktivität stattfindet. Vielen Dank für Ihre Beiträge.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

PeterSisovsky picture PeterSisovsky  ·  3Kommentare

gnujeremie picture gnujeremie  ·  3Kommentare

shedar picture shedar  ·  4Kommentare

dineshkumar20 picture dineshkumar20  ·  3Kommentare

ostapch picture ostapch  ·  4Kommentare