@junart

Codeigniter Google Maps — callback init() AJAX?

Использую библу Google Maps для CI.
Все работает отлично при стандартной загрузки страницы, когда PHP генерит JS и контейнер для карты и отдает в двух переменных $map['js'], $map['html'];
Достаточно во view вывести эти переменные - сложностей с этим нет.

Но, если сгенеренный контейнер и js отдается на страницу через AJAX, карта срабатывает, кроме поиска адреса.
Возникает одна ошибка:

Uncaught TypeError: Cannot read property 'Autocomplete' of undefined


JS, возвращенный Ajax:

<script type="text/javascript">
			//<![CDATA[
			
			var map; // Global declaration of the map
			var lat_longs = new Array();
			var markers = new Array();
			var placesService;
			var placesAutocomplete;
			function initialize() {
				
				var iw = new google.maps.InfoWindow();
				
				 
				var myOptions = {
			  		zoom: 14,
			  		mapTypeId: google.maps.MapTypeId.ROADMAP}
				map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
				
				// Try W3C Geolocation (Preferred)
				if(navigator.geolocation) {
					navigator.geolocation.getCurrentPosition(function(position) {
						map.setCenter(new google.maps.LatLng(position.coords.latitude,position.coords.longitude));
					}, function() { alert("Unable to get your current position. Please try again. Geolocation service failed."); });
				// Browser doesn't support Geolocation
				}else{
					alert('Your browser does not support geolocation.');
				}
			var autocompleteOptions = {
					}
				var autocompleteInput = document.getElementById('address');
				
				placesAutocomplete = new google.maps.places.Autocomplete(autocompleteInput, autocompleteOptions);
				placesAutocomplete.bindTo('bounds', map);
					google.maps.event.addListener(placesAutocomplete, 'place_changed', function() {
						
							    iw.close(); var place = placesAutocomplete.getPlace();
							    if (!place.geometry) {
							      return;
							    }

							    // If the place has a geometry, then present it on a map.
							    if (place.geometry.viewport) {
							      map.fitBounds(place.geometry.viewport);
							    } else {
							      map.setCenter(place.geometry.location);
							      map.setZoom(17);  // Why 17? Because it looks good.
							    }

					  marker_0.setIcon(/** @type {google.maps.Icon} */({
					  url: place.icon,
					  size: new google.maps.Size(71, 71),
					  origin: new google.maps.Point(0, 0),
					  anchor: new google.maps.Point(17, 34),
					  scaledSize: new google.maps.Size(35, 35)
					}));
					marker_0.setPosition(place.geometry.location);
					marker_0.setVisible(true);

							    var address = '';
							    if (place.address_components) {
							      address = [
							        (place.address_components[0] && place.address_components[0].short_name || ''),
							        (place.address_components[1] && place.address_components[1].short_name || ''),
							        (place.address_components[2] && place.address_components[2].short_name || '')
							      ].join(' ');
							    }  iw.open(map, marker_0);
					});
					google.maps.event.addListener(map, "bounds_changed", function(event) {
    			if (!centreGot) {
								var mapCentre = map.getCenter();
								marker_0.setOptions({
									position: new google.maps.LatLng(mapCentre.lat(), mapCentre.lng()) 
								});
							}
						centreGot = true;
  			});
			
			var myLatlng = new google.maps.LatLng(35.731149, 4.5094663);	
			var markerOptions = {
				map: map,
				position: myLatlng,
				draggable: true		
			};
			marker_0 = createMarker(markerOptions);
			
				google.maps.event.addListener(marker_0, "dragend", function(event) {
					$("#mapX").val(event.latLng.lat());$("#mapY").val(event.latLng.lng());
				});
				
			
			}
		
		
		function createMarker(markerOptions) {
			var marker = new google.maps.Marker(markerOptions);
			markers.push(marker);
			lat_longs.push(marker.getPosition());
			return marker;
		}
		function placesCallback(results, status) {
				if (status == google.maps.places.PlacesServiceStatus.OK) {
					for (var i = 0; i < results.length; i++) {
						
						var place = results[i];
					
						var placeLoc = place.geometry.location;
						var placePosition = new google.maps.LatLng(placeLoc.lat(), placeLoc.lng());
						var markerOptions = {
				 			map: map,
				        	position: placePosition
				      	};
				      	var marker = createMarker(markerOptions);
				      	marker.set("content", place.name);
				      	google.maps.event.addListener(marker, "click", function() {
				        	iw.setContent(this.get("content"));
				        	iw.open(map, this);
				      	});
				      	
				      	lat_longs.push(placePosition);
					
					}
					
				}
			}
			
			function loadScript() {
				var script = document.createElement("script");
  				script.type = "text/javascript";
  				script.src = "http://maps.google.com/maps/api/js?sensor=false&libraries=places&callback=initialize";
  				document.body.appendChild(script);
			}
			window.onload = loadScript;
			
			//]]>
			</script>


Поле, куда вводится адрес для поиска имеет id = "address"

Функции автопоиска:

placesAutocomplete = new google.maps.places.Autocomplete(autocompleteInput, autocompleteOptions);


В целом, проблема как я понял асинхронности вызова функций. Текст ошибки представил выше.
Кто сможет помочь с этой проблемой - тот настоящий гуру JS, потому что никто из спецов не смог решить
  • Вопрос задан
  • 2800 просмотров
Пригласить эксперта
Ответы на вопрос 1
dpigo
@dpigo
Front-end developer
Можно поподробнее рассказать, что происходит на странице? Когда происходит AJAX запрос, куда он происходит и зачем, что должно быть возвращено и как обработано?

Пока очевидно, только то, что ошибка у вас из-за того, что google.maps.places === "undefined".

Чтобы не возникало проблем с асинхронностью нужно грамотно расставить обработчики/генераторы событий в колбеках.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы