标记不显示在谷歌地图上,但在控制台中没有错误

Have been pulling my hair out about this for a while: trying to use json to get lat/lng values from my database and then use these values to output markers onto a google map. Currently the map is displaying without the markers and there are no errors in the console. Any help would be greatly appreciated!

 <script type="text/javascript">
       var map = null;

       function addMarker(lat,lng) {
             marker = new google.maps.Marker({
             position: new google.maps.LatLng(lat,lng),
             map: map,
           });
     }


      function initialize() {
      var mapOptions = {
      center: {lat: 54.872128, lng: - 6.284874},
      zoom: 13
     };
    map = new google.maps.Map(document.getElementById('map-canvas'),
    mapOptions);

   $(document).ready(function(){

   $.getJSON('MarkersController.php', function(data){


         var locations = JSON.parse(data);

         for(var i =0; i<locations.length; i++){
               addMarker(locations['lat'], locations['lng']);
      }
});
});


}

 google.maps.event.addDomListener(window, 'load', initialize);

The php script for retrieving from mysql:

<?php

include('DB_INFO.php');

// Opens a connection to a MySQL server.

$connection = mysqli_connect($server, $username, $password);

if (!$connection) {
    die('Not connected : ' . mysqli_error());
}
// Sets the active MySQL database.
$db_selected = mysqli_select_db($database, $connection);

if (!$db_selected) {
    die('Can\'t use db : ' . mysqli_error());
}

// Selects all the rows in the markers table.
$query = 'SELECT * FROM tester';
$result = mysqli_query($query);

if (!$result) {
    die('Invalid query: '. mysqli_error());
}

$list = array();
while ($row = mysqli_fetch_assoc($result)) {
    $list[] = $row;
}
header('Content-Type: application/json');
echo json_encode($list);
?>

If you have a collection of marker i think you should use this way iteranting on the collection and assignd the i element :

for(var i =0; i<locations.length; i++){
  addMarker(locations[i].lat, locations[i].lng);
}

proof of concept fiddle

You may give it a try by changing to below.

while ($row = mysqli_fetch_assoc($result)) {
    //Assuming "lat" is column name in tester table. Please change it if required.
    $lat= $rows['lat'];

    //Assuming "lng" is column name in tester table. Please change it if required.
    $lng= $rows['lng'];

    $list[] = array('lat' => $lat, 'lng' => $lng);
}

You want to use something like this:

google.maps.event.addListenerOnce(map, 'idle', function(){
  // Code Here..but jquery might load first or last.. see below.
});

If i am not mistaken, Your DOM is ready before your map. I normally create a function that is called twice, second call it loads the JS... so first call is normally jQuery and second is maps ready.. Then run any map related code there.

Example Of How I Do It.. in very basic terms...

var iLoadPoints = 0;
function mapReady() {
    if (iLoadPoints==2) {   // Map & jQuery Ready To Use
        // RUN CODE HERE... At this point, run the getJSON and so on...
    } else {    // Loader Not Ready... Escape function and ignore until next call
        return false;
    }
}

$(function() {
    iLoadPoints += 1;
    mapReady();
});
google.maps.event.addListenerOnce(map, 'idle', function(){
    iLoadPoints += 1;
    mapReady();
});

I am taking assumption that if you echo the lat/long to console that you get them... as in the data does exist correctly.

EDIT: as also suggested and just noticed, the loop does need to use the i variable to select the current item in the loop as shown/suggested by scaisEdge.

for(var i =0; i<locations.length; i++){
    addMarker(locations[i].lat, locations[i].lng);
}

Modified From Your Comment: I believe more like this...

var iLoadPoints =0; 
function mapReady(){ 
    if(iLoadPoints === 2){
        initialize(); 
    }else {
        return false;
    }
} 
google.maps.event.addListenerOnce(map, 'idle', function(){ 
    iLoadPoints+=1; 
    mapReady(); 
}); 
google.maps.event.addDomListener(window, 'load', function(){
    iLoadPoints+=1; 
    mapReady(); 
}); 

You can also shorten the mapReady to something more like..

function mapReady(){ 
    if(iLoadPoints === 2) initialize(); 
} 

The whole idea is mapReady is a simple catch... You can add the if statement to the initialize function.. same effect, the whole concept is you need to wait for two differently timed Ready events, it can be done with two booleans or other methods..

In past testing, if i load a website from my localhost and have something like google maps.. The local jQuery will be instant and gmaps will always lag behind.. So at times i would experience failure to load a already configured/data driven map.

Or further more.. this alone should work the same..

var iLoadPoints =0; 
google.maps.event.addListenerOnce(map, 'idle', function(){ 
    iLoadPoints+=1; 
    if (iLoadPoints===2) initialize(); 
}); 
google.maps.event.addDomListener(window, 'load', function(){
    iLoadPoints+=1; 
    if (iLoadPoints===2) initialize(); 
}); 

I made this using prototypes, the code is much more cleaner. An example (supose you are using jquery):

Create 3 scripts:

  1. Map script
  2. JSONParser script
  3. Main script

First Create the prototype functions for work with google maps:

 var MapUtil = (function($) {

    var mapProp = {
        center: new google.maps.LatLng(-38.4529181, -63.5989206),
        zoom: 4,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    /**
     * @returns
     * Maps options for create a google map
     */
    function getMapProperties() {
        return mapProp;
    }

    /**
     * Create simple marker
     * @param lat
     * Latitude for the marker
     * @param lng
     * Longitude for the marker
     * @param myMap
     * Actual map
     * @returns
     * Return a new google map marker
     */
     function simpleMarker(lat, lng, myMap) {
         var marker = new google.maps.Marker({
             //add the marker options
             position: new google.maps.LatLng(lat, lng),
             draggable:true,
             animation: google.maps.Animation.DROP,
             map: myMap,
         });

        return marker;
     }

    return {
        getMapProperties: getMapProperties,
        simpleMarker: simpleMarker,
    };

})(jQuery);

Then create the JSONParser for transform the JSON to javascript objects:

var JSONParser = (function($){

    /**
     * @return An array with the markers parsed
     */
    function getMarkers(json) {
        var markers = [];
        for (int i = 0; i < json.length; i++) {
            markers.push({json[i].lat,json[i].lng});
        }

        return markers;
    }

    return {
        getMarkers : getMarkers,
    };

})(jQuery);

And you main script:

$(document).ready(function() {
    var myMap = null;

    //add the map to the page
    google.maps.event.addDomListener(window, 'load', initialize);

    /**
     * Init Google Maps
     */
    function initialize() {
        var map=new google.maps.Map(document.getElementById("googleMap"), 
                MapUtil.getMapProperties());
        myMap = map;

        createMarkers();
    }

    function createMarkers() {
        //retrieve the information
        $.ajax({             
            type: 'post',
            url: 'MarkersController.php',
            data: {},
            success: function (data) {
                var json= $.parseJSON(data);
                var markers = JSONParser.getMarkers(json);

                for (var i = 0; i < markers.length; i++) {
                    MapUtil.simpleMarker(marker[i].lat, marker[i].lng, myMap);
                }
            }
        });
    }
});

Then add the scripts to the html in this order:

<script src="...path.../map-utils.js"></script>
<script src="...path.../json-pareser.js"></script>
<script src="...path.../main.js"></script>

For other functionality about the map or json add extra methods!