2017-11-17 15 views
9

Tôi đang tạo hình ảnh Power BI tùy chỉnh, vì vậy tôi có quyền truy cập vào tệp javascript được nền tảng tiêu thụ. Tôi không có quyền truy cập vào bất kỳ đánh dấu nào, chỉ có một yếu tố được tiêm vào nơi tôi gắn kết hình ảnh của tôi.Gọi lại không được gọi

Tôi cố gắng để gắn kết một Bing Map, các tài liệu giống như thế này:

<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 để kịch bản có một param callback chuỗi truy vấn trong đó bao gồm tên của hàm để gọi.

Vì tôi không có quyền truy cập vào đánh dấu, tôi đang cố gắng làm mọi thứ động trong trình tạo hình ảnh của tôi. Tôi tạo ra một hàm, di chuyển nó đến phạm vi toàn cục, và sau đó tôi thêm chuỗi truy vấn var để tham chiếu nó, nhưng nó không bao giờ được gọi. Bạn có thể thấy bất cứ điều gì tôi có thể bị mất?

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

Trả lời

3

Bạn đã xác định các chức năng cần thiết để thực hiện những gì bạn muốn. Tuy nhiên, trong đoạn trích bạn đã đưa ra, bạn không thực sự gọi theo số moveMethodsIntoGlobalScope(), đó là lý do tại sao loadMapScenario không được xác định. Chỉ cần thêm dòng này trước khi tiêm tập lệnh.

moveMethodsIntoGlobalScope(methodsToPutInGlobalScope); 
2

Sử dụng foo === undefined hoạt động khác nhau tùy thuộc vào thời gian chạy. Thay vào đó, hãy sử dụng typeof foo khi kiểm tra xem biến có tồn tại hay không.

Bạn đang sử dụng script.async sẽ làm cho tập lệnh tải sau tất cả các tập lệnh khác, có thể bạn muốn tải tập lệnh đó trước các tập lệnh khác.

Lừa khác là để chiếm quyền điều khiển window.onload ...

3

Để đưa một phương pháp thành phạm vi toàn cầu trong trình duyệt, bạn có lẽ có thể làm gì với một cái gì đó đơn giản hơn, như:

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

tôi đừng nghĩ rằng bạn cần moveMethodsIntoGlobalScope hoặc methodsToPutInGlobalScope - bạn không gọi đến một trong số họ từ mã này, trong mọi trường hợp.

1

Tôi nghĩ rằng mã này là đủ:

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

Đây là một JSFiddle bạn có thể thử với API_KEY của bạn: https://jsfiddle.net/9mfzrcfd/2/

Các vấn đề liên quan