Как я могу использовать карты bing, загруженные из внешнего cdn внутри моего приложения vuejs? - PullRequest
0 голосов
/ 05 ноября 2018

Как использовать API Bing Maps в приложении Vue JS для отображения карты?

Примечание : я использую карты Bing V8 и vuejs 2.5.17.

Это мой шаблон

<template>
   <div id="map"></div>
</template>

Это мой стиль

<style lang="scss" scoped>
   #map {
      height: 300px;
      width: 500px;
   }
</style>

Это моя часть скрипта (я использую объектный компонент класса)

mounted() {
   let mapElement: HTMLElement = <HTMLElement>document.getElementById("map")
   var map = new Microsoft.Maps.Map(mapElement, {
     credentials: [API_KEY]
   });
}

Вот так я включаю внешний скрипт из cdn в мое приложение. После некоторых исследований я нашел и попробовал 2 варианта ниже

Вариант 1: я включил скрипт непосредственно в мой файл index.html:

<!-- index.html -->
...
<head>
   ...
   <script src="https://www.bing.com/api/maps/mapcontrol?key=[API_KEY]" async defer></script>
</head>

Вариант 2. Я программно внедряю скрипт в документ из моего компонента в смонтированный метод, как показано ниже

mounted() { 
   // Add programmaticaly the external Bing maps api script
   var scriptTag = document.createElement("script");
   scriptTag.src = "https://www.bing.com/api/maps/mapcontrol";
   scriptTag.id = "bingApiMaps";
   // Inject the dynamic script in the DOM
   document.head.appendChild(scriptTag);
   ...
}

В обоих случаях у меня возникает следующая ошибка, и я не понимаю, почему:

[Vue warn]: Error in mounted hook: "ReferenceError: Microsoft is not defined"

Ответы [ 2 ]

0 голосов
/ 18 марта 2019

Я расшифровал ответ rdhainaut на JavaScript:

mounted: function() {
  if (document.getElementById("scriptBingMaps")) {
    return; // already loaded
  }

  // Add a global function for the callback from Bing Maps api
  window.OnLoadBingMapsApi = () => this.InitMap();

  // Add programmaticaly the external Bing maps api script
  var scriptTag = document.createElement("script");
  scriptTag.src = "https://www.bing.com/api/maps/mapcontrol?callback=OnLoadBingMapsApi&key=[BING_API_KEY]";
  scriptTag.id = "scriptBingMaps";

  // Inject the dynamic script in the DOM
  document.head.appendChild(scriptTag);
},
methods: {
  InitMap: function() {
    var mapElement = this.$refs.myMap;

    this.map = new Microsoft.Maps.Map(mapElement, {
      mapTypeId: Microsoft.Maps.MapTypeId.aerial,
      zoom: 15,
      maxZoom: 21,
      //minZoom: 15,
      center: new Microsoft.Maps.Location(52.7759872, -1.5119702),
      maxNetworkLinkDepth: 3
    });
  }
}
0 голосов
/ 05 ноября 2018

После многих неприятностей я понял. API-карта Bing загружается асинхронным способом. Таким образом, объект Microsoft / Microsoft.Maps не доступен напрямую.

Я решил оставить решение 2 для загрузки скрипта (таким образом, скрипт не загружается глобально). Я пытался использовать метод onload на вставленный скрипт, но безуспешно. API Bing Maps имеет возможность вызывать функцию обратного вызова, но эта функция должна быть глобальной. Это мое окончательное рабочее решение

<template>
  <div id="map" ref="map"></div>
</template>

<script lang="ts">
// Vue
import { Vue, Component } from "vue-property-decorator";

@Component
export default class AppMap extends Vue {
  mounted() {
    if (document.getElementById("scriptBingMaps")) {
      return; // already loaded
    }

    // Add a global function for the callback from Bing Maps api
    (<any>window).OnLoadBingMapsApi = () => this.InitMap();

    // Add programmaticaly the external Bing maps api script
    var scriptTag = document.createElement("script");
    scriptTag.src = "https://www.bing.com/api/maps/mapcontrol?callback=OnLoadBingMapsApi";
    scriptTag.id = "scriptBingMaps";
    // Inject the dynamic script in the DOM
    document.head.appendChild(scriptTag);
  }

  private InitMap(): void {
    let mapElement: HTMLElement = <HTMLElement>this.$refs.map;
    var map = new Microsoft.Maps.Map(mapElement, {
      credentials: [API_KEY]
    });
  }
}
</script>

<style lang="scss" scoped>
/* ==========================================================================
   Map
  ========================================================================== */
#map {
  height: 300px;
  width: 500px;
}
</style>

Et voilà! :)

...