【问题标题】:Google map not rendering properly when called via function in a for loop通过 for 循环中的函数调用时,Google 地图无法正确呈现
【发布时间】:2021-02-01 00:32:52
【问题描述】:

我正在 ASP.NET MVC Core 中创建一个项目,我正在尝试创建一个带有坐标的列表并在它旁边显示一个谷歌地图图钉。

地图正在渲染,但显示为灰色/空白。

我的地图列表代码

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Coordinates)
            </th>
        </tr>
    </thead>
    <tbody>
        @{
            int count = 0;
        }
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    <div id="@count" style="height:400px;width:700px;"></div>
                    <script type="text/javascript">myMap('@count', @item.Coordinates)</script>
                    @Html.DisplayFor(modelItem => item.Coordinates)
                </td>
                <td>
                    <a asp-action="Edit" asp-route-id="@item.Coordinates">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Coordinates">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Coordinates">Delete</a>
                </td>
            </tr>
            count++;
        }
    </tbody>
</table>

我正在使用的 JS 函数。它与我的 API 密钥一起加载到 head

    <script type="text/javascript">
        function myMap(divId, coord) {
            var myCenter = new google.maps.LatLng(coord);
            var mapProp = { center: myCenter, zoom: 12, scrollwheel: false, draggable: true, mapTypeId: google.maps.MapTypeId.ROADMAP };
            var map = new google.maps.Map(document.getElementById(divId), mapProp);
            var marker = new google.maps.Marker({ position: myCenter });
            marker.setMap(map);
        }
    </script>

这是我的结果。

当我不在 for 循环中加载地图并使用脚本但使用硬编码参数时,它可以正常工作。

<div id="googleMap" style="height:400px;width:100%;"></div>
<script>
        function myMap() {
            var myCenter = new google.maps.LatLng(@Model.Coordinates);
            var mapProp = { center: myCenter, zoom: 12, scrollwheel: false, draggable: true, mapTypeId: google.maps.MapTypeId.ROADMAP };
            var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
            var marker = new google.maps.Marker({ position: myCenter });
            marker.setMap(map);
        }
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=APIKEY&callback=myMap"></script>

我无法弄清楚我做错了什么,我一直在寻找但找不到任何答案。任何帮助表示赞赏!

【问题讨论】:

  • 您不能以数字开头。您的循环看起来像是用数字命名 div 的 id。例如,尝试在数字前加上 map_。
  • 是的,我一定会试一试的。

标签: javascript c# asp.net-core google-maps-api-3 razor-pages


【解决方案1】:

也许你在地图初始化之前就得到了坐标?尝试在 OnMapReady 事件中进行 api 调用

【讨论】:

  • 我该怎么做?
  • 您的坐标有问题是对的,但@siaznik 编辑的答案有效:)
【解决方案2】:

确保在加载 Google Maps API 后初始化您的地图。为此,只需将 google 网址的 callback 部分指向将处理该问题的函数(参见下面的示例)。

正如 Lee 在他的评论中所说,不要使用数字作为元素 ID。 Lee 建议使用前缀是正确的,您应该考虑使用它。

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Coordinates)
            </th>
        </tr>
    </thead>
    <tbody>
        @{
            int count = 0;
        }
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    <div class="map" id="map_@count" style="height:400px;width:700px;" data-coord="@item.Coordinates"></div>
                    <!-- REMOVED script here and added more data to the div element above -->
                    @Html.DisplayFor(modelItem => item.Coordinates)
                </td>
                <td>
                    <a asp-action="Edit" asp-route-id="@item.Coordinates">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Coordinates">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Coordinates">Delete</a>
                </td>
            </tr>
            count++;
        }
    </tbody>
</table>
<script>
  // this function will be called by google's api once loaded
  function loaded() {
    // assuming each map container has a class "map",
    let maps = document.querySelectorAll('.map');
    maps.forEach(map => initMap(map));
  }
  function initMap(map) {
    var myCenter = new google.maps.LatLng(map.dataset.coord); // retrieving coords from data attribute
    var mapProp = { center: myCenter, zoom: 12, scrollwheel: false, draggable: true, mapTypeId: google.maps.MapTypeId.ROADMAP };
    var map = new google.maps.Map(map, mapProp);
    var marker = new google.maps.Marker({ position: myCenter });
    marker.setMap(map);
  }
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=APIKEY&callback=loaded"></script>

编辑:看看下面的sn-p。我以前没有发现坐标必须作为数字传递。

let maps = document.querySelectorAll('.map')

function loaded() {
  maps.forEach(map => initMap(map))
}

function initMap(element) {
  let xy = element.dataset.coords.split(',').map(a => parseFloat(a))
  let center = new google.maps.LatLng(xy[0], xy[1])
  let props = { center: center, zoom: 12, scrollwheel: false, draggable: true, mapTypeId: google.maps.MapTypeId.ROADMAP };
  let map = new google.maps.Map(element, props);
  let marker = new google.maps.Marker({ position: center });
  marker.setMap(map);
}
.map {
  width: 400px;
  height: 400px;
  background: yellow;
  margin-bottom: 15px;
}
<!-- The British Museum -->
<div class="map" data-coords="51.5145532,-0.1167918"></div>
<!-- Castello Sforzesco -->
<div class="map" data-coords="45.4636261,9.1714131"></div>
<!-- Nordscheleife -->
<div class="map" data-coords="50.3341015,6.9404738"></div>

<script src="https://maps.googleapis.com/maps/api/js?key=&callback=loaded" async defer></script>

【讨论】:

  • 非常感谢您的回答!我认为这看起来是一个更优雅的解决方案。所以我试过这个,但它导致地图仍然是灰色的。我不太熟悉 JS,但是当函数中有 var map 时,将“map”作为参数传递给 initMap 可能存在一些冲突?我假设当通过容器类调用时,我不必将 div id 显式传递给new google.maps.Map
  • 我尝试将var = map 更改为“mapper”,但无济于事。
  • 我回家后试试这个。但是我认为您不必将坐标作为数字传递,至少当我直接从模型中传递它时它应该可以工作,因为在我的示例中为单个地图执行它时它会起作用.. 编辑:虽然也许它现在我们将它们作为属性放在 div 中是不同的吗?
  • 你的编辑很神奇! (在调用 'element.dataset.coords.split...' 后我删除了 's'):) 干得好,非常感谢!
猜你喜欢
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 2013-05-25
  • 1970-01-01
  • 2020-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多