Angular-google-maps: كيفية بدء الوحدة باستخدام متغير apiKey

تم إنشاؤها على ٣ فبراير ٢٠١٧  ·  12تعليقات  ·  مصدر: SebastianM/angular-google-maps

لدي مفتاح google api في خدمة تكوين فردية (طريقة لمشاركة تكوين التطبيق عبر كل التطبيقات).

كيف يمكنني تمرير متغير apiKey إلى الوحدة النمطية داخلNgModule؟

NgModule ({

الواردات: [
BrowserModule ،
CommonModule ،
النماذج
AgmCoreModule.forRoot ({
apiKey: 'YOUR_KEY' // <- لا يمكنني استخدام ثابت !!! كيف يمكنني تمرير متغير؟
})
] ،
الموفرون: [] ،
الإعلانات: [AppComponent] ،
التمهيد: [AppComponent]
}) `

stale discussion / question

التعليق الأكثر فائدة

يعتمد على نوع أداة البناء التي تستخدمها (مثل angular-cli أو webpack المخصص أو ...) والمكان الذي يجب أن يأتي منه المتغير.
قد يكون هذا صعبًا بعض الشيء. خاصة عندما تريد أيضًا استخدام التحويل البرمجي AOT ، والذي يمنع الكثير من التعليمات البرمجية الديناميكية داخل @NgModule .

الحل الذي قمت بتنفيذه حاليًا يتجاوز "موفر التكوين الكسول" في وحدة التطبيق الرئيسية.

في الوحدة حيث أستخدم الخريطة بالفعل ، أستخدم تكوينًا فارغًا في 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 .

الحل الذي قمت بتنفيذه حاليًا يتجاوز "موفر التكوين الكسول" في وحدة التطبيق الرئيسية.

في الوحدة حيث أستخدم الخريطة بالفعل ، أستخدم تكوينًا فارغًا في 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 - لذلك يُرجع الخطأ الرئيسي المفقود.

في حالة الاستخدام الخاصة بي ، أنا أستخدم المكون الإضافي لتعريف الويب الموسع لإضافة إعدادات تهيئة عامة لوقت الترجمة (مفاتيح واجهة برمجة التطبيقات التي يمكن أن تتغير بناءً على نوع البناء وما إلى ذلك).

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 لكن لا يمكنني تشغيل هذا ، ما

هذا هو الكود الخاص بي ما الخطأ الذي أفعله؟

"
@ حقن ()
فئة التصدير GoogleMapsConfig تنفذ LazyMapsAPILoaderConfigLiteral {
مفتاح api العام: سلسلة ؛
البناء() {
إذا (إنتاج البيئة) {
this.apiKey = مفتاح تم إدخاله هنا
} ؛
}
}
NgModule ({
الإعلانات: [
AppComponent
] ،
الواردات: [
BrowserModule ،
النماذج
ReactiveFormsModule ،
HttpModule ،
AppRoutingModule ،
NgbModule.forRoot () ،
نويسلايدر
AgmCoreModule.forRoot ()
] ،
الموفرون: [
{توفير: LAZY_MAPS_API_CONFIG ، useClass: GoogleMapsConfig}
] ،
التمهيد: [AppComponent]
})
فئة التصدير AppModule {

}
"

هل أنت متأكد من أن if (environment.production) سيحل في أي وقت إلى true؟

لقد حللت هذا شكرا لملاحظاتك

daBishMan أو kyranjamie ، إذا kyranjamie ، يبدو أن يتعلق بـ AOT ،

@ 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]
    }

المرجع إلى فئة التكوين هو استبدال متغير webpack-time الذي يتم إعداده لخريطة المتغيرات المستخدمة في أوضاع Dev أو Prod.

مرحبا

تمكنت من تحقيق المفتاح الديناميكي ، مثل @ jorrit-wehelp comments ، ولكن في السيناريو الخاص بي بعد تسجيل خروج المستخدم وتسجيل الدخول ، لم يتم تحديث قيمة agmKey ولن تتمكن من رؤية الخريطة

ما فعلته كان في مكون الوحدة الخاص بنا ، قمنا بإضافة الكود التالي
لذلك قمت بنقل class GoogleMapsConfig و {provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig} داخل الخريطة @component

"...
استيراد {LAZY_MAPS_API_CONFIG، LazyMapsAPILoaderConfigLiteral} من "@ agm / core" ؛
استيراد {AuthService} من "@ pl-core / _services" ؛

@ حقن () ؛
فئة GoogleMapsConfig تنفذ LazyMapsAPILoaderConfigLiteral {
مفتاح api العام: سلسلة ؛
البناء() {
console.log ("خرائط داخلية") ؛ // لا يتم عرض هذا في وحدة التحكم
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']،
الموفرون: [{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>

لا أعرف ما إذا كان هذا سينطبق على الجميع أو إذا كان هذا يعتمد على أساس كل حالة على حدة ، لكنني اكتشفت أن هذا نتيجة لعملية تجميع AOT في Angular ، بدلاً من مشكلة في agm نفسها. فيما يلي نظرة عامة على الموقف الذي كان لدي.

أردت أن أجعل تكوين مفتاح API مدفوعًا بدلاً من سلسلة مشفرة صلبة ، بحيث يسمح لي التنقل عبر بيئات مختلفة باستخدام مفاتيح API مختلفة ومراقبة استخدام API. من أجل القيام بذلك ، قمت بضخ بعض JavaScript في نهاية .NET الخلفية بالقيمة التي أحتاجها في مساحة الاسم العالمية ، المخزنة في 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. ومع ذلك ، فقد اتضح أن مترجم AOT يدعم فقط التضمين في وقت الترجمة . على نحو فعال ، ما كان يحدث هو خطأ " المتغيرات والثوابت التي تمت تهيئتها فقط " دون انبعاث خطأ من Angular CLI. بمجرد إجراء التبديل لاستخدام نوع ما من مزود LAZY_MAPS_API_CONFIG باستخدام فصل دراسي تمكنت من استخدامه بنجاح.

تم وضع علامة على هذه المشكلة تلقائيًا على أنها قديمة نظرًا لعدم وجود نشاط حديث لها. سيتم إغلاقه إذا لم يحدث أي نشاط آخر. شكرا لمساهماتكم.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

n1t3w0lf picture n1t3w0lf  ·  3تعليقات

Halynsky picture Halynsky  ·  3تعليقات

ChrisDevinePimss picture ChrisDevinePimss  ·  3تعليقات

PeterSisovsky picture PeterSisovsky  ·  3تعليقات

supran2811 picture supran2811  ·  4تعليقات