简体   繁体   中英

Google map not rendering properly when called via function in a for loop

I'm making a project in ASP.NET MVC Core and I am trying to create a list with coordinates and display a google map pin next to it.

The map is rendering but the it is greyed out/blank.

My code for the list with the maps

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

The JS function I'm using. It is loaded in head together with my API key

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

And this is my result.

地图未正确渲染

When I am not loading the map in a for loop and using the script but with hardcoded parameters it works fine.

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

地图渲染正确

I cant figure out what I'm doing wrong, I have been looking but cannot find any answers. Any help is appreciated!

Make sure you initialise your maps after the Google Maps API is loaded. To do that just point the callback part of the google's url to the function that will handle that (see example below).

Also as Lee stated in his comment do not use numbers as element ids. Lee's suggestion to use a prefix is spot on and you should consider using it.

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

Edit: Have a look at below snippet. I haven't spotted before that the coords have to be passed as numbers.

 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>

maybe you get the cordinates before the map is initialized? try make the api call inside OnMapReady event

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM