Google Map API V3无法在聚合物元素中运行

时间:2015-05-09 14:40:06

标签: javascript html5 google-maps-api-3 polymer

我创建了聚合物元素并在其中添加了Google Map。如果我将聚合物元素的代码直接写入我想要使用它的主文件中,但是如果我将其代码保存在单独的文件中并通过导入使用它然后它在控制台中给出以下错误,它是否正常工作:

  

无法执行'写'在'文件':不可能写   从异步加载的外部脚本转换为文档,除非   它被明确地打开了。

这是my-map.html文件的代码:

<link rel="import" href="bower_components/polymer/polymer.html">
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<polymer-element name="my-map">
        <template>
            <style type="text/css">
            :host{
                display: block;
            }
                #mapCanvas {
            height: 100%;
            margin: 0px;
            padding: 0px;
          }
            </style>
            <div id="mapCanvas"></div>
        </template>
        <script type="text/javascript">
            Polymer({
                map:null,
                ready:function(){

                    this.map = new google.maps.Map(this.$.mapCanvas, {
                    center: new google.maps.LatLng(41, -91),
                    disableDefaultUI: true,
                    zoom: 5
                     });
                }
            });
        </script>
    </polymer-element>

这是主文件index.html的代码:

<!DOCTYPE html>
<html>
<head>
    <title>My Map</title>

    <script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
    <link rel="import" href="my-map.html">
</head>
<body>
<my-map style="height:500px,width:500px;"></my-map>
</body>
</html>

哪里有问题? 如果我在index.html文件中编写my-map.html文件的代码,那么它可以完美运行。

1 个答案:

答案 0 :(得分:1)

粗糙的文件结构:

  • file:index.html
  • file:my-map.html
  • 目录:bower_components /
    • 目录:core-component-page /...
    • 目录:polymer /...
    • 目录:webcomponentsjs /...

当google-maps lib包含在聚合物元素的定义之上时,google-maps似乎无法在聚合物元素上构建地图,可能有一个/几个原因可归咎于此。但至少有两种解决方案适合我。

第一个解决方案

尝试从您的聚合物元素中排除google-maps lib并将其包含在index.html文件中:

的index.html:

<!DOCTYPE html>
<html>
<head>
    <title>My Map</title>
    <!-- include google maps lib into your main index.html file -->
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
    <script src="bower_components/webcomponentsjs/webcomponents.js"></script>
    <link rel="import" href="my-map.html">
</head>
<body>
    <my-map width="500px" height="500px"></my-map>
</body>
</html>

聚合物元件(MY-map.html):

<link rel="import" href="bower_components/polymer/polymer.html">
<polymer-element name="my-map" attributes="width height">
    <template>
        <style type="text/css">
            :host{
                display: block;
            }
            #mapCanvas {
                margin: 0px;
                padding: 0px;
            }
        </style>
        <div id="mapCanvas" style="width:{{width}};height:{{height}}"></div>
    </template>
    <script>
        Polymer({
            map:null,
            width: '100px',// default width
            height: '100px',// default height
            ready:function(){

                // map canvas lies within shadow-dom so it not accessible by ordinary *querySelector*, *querySelectorAll* or *getElementById* methods but this is a way: this.$.mapCanvas 
                this.map = new google.maps.Map(
                                this.$.mapCanvas,
                                { center: new google.maps.LatLng(41, -91),
                                  disableDefaultUI: true,
                                  zoom: 5
                                }
                );
            }
        });
    </script>
</polymer-element>

第二个解决方案:

尝试使用google maps lib(url-part:&amp; callback = callback )的回调参数,并将google maps lib包含在聚合物元素的定义中:

的index.html:

<!DOCTYPE html>
<html>
<head>
    <title>My Map</title>
    <script src="bower_components/webcomponentsjs/webcomponents.js"></script>
    <link rel="import" href="my-map.html">
</head>
<body>
    <!-- use default width/height -->
    <my-map></my-map>
</body>
</html>

聚合物元件(MY-map.html):

<link rel="import" href="bower_components/polymer/polymer.html">
<polymer-element name="my-map" attributes="width height">
    <template>
        <style type="text/css">
            :host{
                display: block;
            }
            #mapCanvas {
                margin: 0px;
                padding: 0px;
            }
        </style>
        <div id="mapCanvas" style="width:{{width}};height:{{height}}"></div>
    </template>
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&callback=callback"></script>
    <script>

        // use IIFE to encapsulate all defined variables to prevent them from being assigned to window object unintentionally
        (function(){

            var googleMapsReady = false;

            var myMapPolymer;
            var htmlCanvasMap;

            function callback(){

                googleMapsReady = true;

                if(htmlCanvasMap){
                    buildUpMap(htmlCanvasMap);
                }

            }
            // !!! unfortunately you have to assign callback function to window object
            // because this function has to be accessible globally  otherwise google maps lib will not find it and throws an error
            window.callback = callback;

            // function to show a google map on your site that takes a html element on which a map should be shown
            function buildUpMap(htmlmap){

                var map = new google.maps.Map(
                                    htmlmap,
                                    { center: new google.maps.LatLng(38, -91),
                                      disableDefaultUI: true,
                                      zoom: 8
                                    }
                );

                // at last assign google map object as property to polymer element
                myMapPolymer.map = map;

            }

            // polymer element code definition
            Polymer({
                map:null,
                width: '100px',// default width
                height: '100px',// default height
                ready:function(){

                    myMapPolymer = this;

                    // assign map canvas(div) to varible in order to use it for building up a map, 
                    htmlCanvasMap = this.$.mapCanvas;

                    if(googleMapsReady){
                        buildUpMap(htmlCanvasMap);
                    }

                }
            });

        })();

    </script>
</polymer-element>

在第二个解决方案中,仍有机会将初始化的Google地图对象指定为聚合物元素的属性:

  • 变量 googleMapsReady 在加载谷歌地图并准备好使用时设置,在 Polymer.ready 功能中进行检查。

  • 否则,如果在回调之前调用 Polymer.ready ,则会分配变量 htmlCanvasMap ,因此 true 回调功能中检查时。

希望这有帮助。