2017-11-17 15 views
9

Ich erstelle eine benutzerdefinierte Power BI-Visualisierung, also habe ich Zugriff auf eine Javascript-Datei, die von der Plattform verbraucht wird. Ich habe keinen Zugriff auf Markup, nur ein Element, das injiziert wird, wo ich meine Visualisierung mounten soll.Rückruf wird nicht aufgerufen

ich eine Bing Karte zu montieren versuche, sehen die Dokumente wie folgt aus:

<div id='myMap' style='width: 100vw; height: 100vh;'></div> 

    <script type='text/javascript'> 
      var map; 
      function loadMapScenario() { 
       map = new Microsoft.Maps.Map(document.getElementById('myMap'), {}); 
      } 


    </script> 

    <script type='text/javascript' src='https://www.bing.com/api/maps/mapcontrol?key=YourBingMapsKey&callback=loadMapScenario' async defer></script> 

Die URL für das Skript hat einen callback Abfragezeichenfolgeflag param, die den Namen der Funktion enthält aufzurufen.

Da ich keinen Zugriff auf das Markup habe, versuche ich alles dynamisch im Konstruktor meiner Visualisierung zu machen. Ich erstelle eine Funktion, verschiebe sie in den globalen Bereich und füge dann querystring var hinzu, um sie zu referenzieren, aber sie wird nie aufgerufen. Kannst du etwas sehen, das ich vermisse?

constructor(options: VisualConstructorOptions) { 
     this.host = options.host; 
     this.elem = options.element; 
     const self = this; 

     function moveMethodsIntoGlobalScope(functionName){ 
      var parts = functionName.toString().split('\n'); 
      eval.call(window, parts.splice(1, parts.length - 2).join('')); 
     } 

     function methodsToPutInGlobalScope(){ 
      function loadMapScenario(){ 
       console.log("finally called loadMapScenario"); 
      } 
     } 

     const script = document.createElement('script'); 
     script.type = 'text/javascript'; 
     script.async = true; 

     console.log(loadMapScenario === undefined); // false, definitely in global scope 
     script.src = 'https://www.bing.com/api/maps/mapcontrol?key=xxxxxxxxxx&callback=loadMapScenario'; 
     document.getElementsByTagName('head')[0].appendChild(script); 

Antwort

3

Sie haben die Funktionen definiert, die erforderlich sind, um das zu erreichen, was Sie möchten. In dem Ausschnitt, den Sie angegeben haben, rufen Sie jedoch nicht moveMethodsIntoGlobalScope() auf, weshalb loadMapScenario nicht definiert ist. Fügen Sie diese Zeile einfach hinzu, bevor Sie das Skript einfügen.

moveMethodsIntoGlobalScope(methodsToPutInGlobalScope); 
2

Verwendung von foo === undefiniert verhält sich je nach Laufzeit unterschiedlich. Verwenden Sie stattdessen typeof foo, wenn Sie prüfen, ob eine Variable existiert.

Sie verwenden script.async, wodurch das Skript nach allen anderen Skripten geladen wird. Wahrscheinlich möchten Sie es jedoch vor den anderen Skripten laden.

Ein weiterer Trick ist window.onload kapern ...

3

Um eine Methode in den globalen Bereich im Browser zu setzen, können Sie wahrscheinlich mit etwas einfacher, machen zu tun:

window.loadMapScenario =() => { 
    console.log("finally called loadMapScenario") 
} 

I glaube nicht, dass Sie moveMethodsIntoGlobalScope oder methodsToPutInGlobalScope brauchen - Sie rufen keines von ihnen von diesem Code in jedem Fall an.

1

Ich denke, dieser Code genug ist:

window.loadMapScenario = function() { 
    console.log("finally called loadMapScenario"); 
} 

const script = document.createElement('script'); 
script.type = 'text/javascript'; 
script.async = true; 
script.src = `https://www.bing.com/api/maps/mapcontrol?key=${API_KEY}&callback=loadMapScenario`; 
document.getElementsByTagName('head')[0].appendChild(script); 

hier ein JSFiddle ist, können Sie mit Ihrem API_KEY versuchen: https://jsfiddle.net/9mfzrcfd/2/

Verwandte Themen