没有调用回调

时间:2017-11-17 18:45:26

标签: javascript powerbi

我正在构建自定义Power BI可视化,因此我可以访问平台使用的javascript文件。我无权访问任何标记,只有一个元素被注入到我可以安装我的可视化的位置。

我正在尝试安装Bing地图,文档看起来像这样:

    <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有一个callback查询字符串参数,其中包含要调用的函数的名称。

鉴于我无法访问该标记,我试图在我的可视化构建器中动态执行所有操作。我创建一个函数,将其移动到全局范围,然后我添加querystring var来引用它,但它永远不会被调用。你能看到我可能遗失的任何东西吗?

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

4 个答案:

答案 0 :(得分:3)

您已经定义了完成所需功能所需的功能。但是,在您提供的代码段中,您实际上并没有调用moveMethodsIntoGlobalScope(),这就是loadMapScenario未定义的原因。只需在注入脚本之前添加此行。

moveMethodsIntoGlobalScope(methodsToPutInGlobalScope);

答案 1 :(得分:3)

要将方法放入浏览器的全局范围,您可以使用更简单的方法,例如:

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

我认为您不需要moveMethodsIntoGlobalScopemethodsToPutInGlobalScope - 在任何情况下,您都不会从此代码中调用其中任何一个。

答案 2 :(得分:2)

使用foo === undefined的行为因运行时而异。在检查变量是否存在时,请使用typeof foo。

您正在使用script.async,这将使脚本在所有其他脚本之后加载,您可能希望在其他脚本之前加载它。

另一个伎俩就是劫持window.onload ......

答案 3 :(得分:2)

我认为这段代码已经足够了:

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

以下是您可以尝试使用API​​_KEY的JSFiddle:https://jsfiddle.net/9mfzrcfd/2/