2017-11-17 49 views
9

Buduję niestandardową wizualizację Power BI, więc mam dostęp do pliku javascript, który jest zużywany przez platformę. Nie mam dostępu do żadnego znacznika, tylko element, który jest wstrzykiwany, gdzie mam zamontować moją wizualizację.Odwołanie nie jest wywoływane

Próbuję zamontować Bing mapy, dokumentacja wyglądać następująco:

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

URL do skryptu ma param callback ciągu kwerendy, która zawiera nazwę funkcji powołania.

Biorąc pod uwagę, że nie mam dostępu do znaczników, staram się robić wszystko dynamicznie w moim konstruktorze wizualizacji. Tworzę funkcję, przenoszę ją do zakresu globalnego, a następnie dodaję zmienną kwarystringową, aby ją odnieść, ale nigdy nie zostanie ona wywołana. Czy widzisz coś, czego może mi brakować?

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

Odpowiedz

3

Zdefiniowałeś funkcje wymagane do osiągnięcia tego, co chcesz. Jednak we fragmencie, który podałeś, w rzeczywistości nie wywołujesz moveMethodsIntoGlobalScope(), dlatego loadMapScenario jest niezdefiniowana. Po prostu dodaj tę linię przed wstrzyknięciem skryptu.

moveMethodsIntoGlobalScope(methodsToPutInGlobalScope); 
2

Stosując bla === niezdefiniowane zachowuje się różnie w zależności od wykonywania. Zamiast sprawdzania, czy istnieje zmienna, należy użyć typeof foo.

Używasz skryptu script.async, który spowoduje, że skrypt zostanie załadowany po wszystkich innych skryptach, ale prawdopodobnie chcesz go wczytać przed innymi skryptami.

Inną sztuczką jest porwać window.onload ...

3

Mówiąc metodę w zakresie globalnym w przeglądarce, prawdopodobnie można zrobić z czegoś prostszego, jak:

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

I nie myśl, że potrzebujesz moveMethodsIntoGlobalScope lub methodsToPutInGlobalScope - w żadnym wypadku nie wywołujesz żadnego z nich z tego kodu.

1

myślę, że ten kod jest na tyle:

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

Oto JSFiddle można spróbować z API_KEY: https://jsfiddle.net/9mfzrcfd/2/