在将谷歌地图API升级到3.35版后,我在使用谷歌地图API时遇到了问题。目标是在表单中显示地图,以便用户可以定义地理位置。我正在使用Django 1.11.12和CanJS 2.0.2。
这是代码(为简单起见进行了简化(,适用于Google地图API版本3.34,但不适用于版本3.35。
models.py
from django.db import models
from maps.models import JSONField
class Institution(models.Model):
geolocation = JSONField(blank=True, null=True)
地图/模型.py
from django.db import models
from maps.forms import LatLngWidget
class JSONField(models.TextField):
def formfield(self, **kwargs):
kwargs.update({'widget': LatLngWidget()})
return super(JSONField, self).formfield(**kwargs)
地图/表格.py
from django import forms
from django.conf import settings
from django.contrib.staticfiles.templatetags.staticfiles import static
from django.utils.safestring import mark_safe
from django.template.loader import render_to_string
from django.forms.widgets import Widget
class LatLngWidget(Widget):
def __init__(self, attrs=None):
super(LatLngWidget, self).__init__(attrs)
self.width = 640
self.height = 480
def render(self, name, value, attrs=None):
data = dict(name=name, value=value, width=self.width, height=self.height)
html = render_to_string("maps/widget.html", data)
return mark_safe(html)
def _media(self):
return forms.Media(css={"all": [static("maps/css/gmap.css"),],},)
media = property(_media)
小部件.html
<div class="map-container" id="geolocation-container">
<div class="map-box">
<div class="map map-canvas" id="gmap-geolocation"></div>
</div>
</div>
<script src="https://maps.googleapis.com/maps/api/js?v=3.35&key=xxx"></script>
<script type="text/javascript">
Map = can.Control({
init: function(el, options) {
this.map = null;
this.marker = null;
this.name = options.name;
this.lat = options.lat || 0;
this.lng = options.lng || 0;
this.zoom = options.zoom || 2;
this.createMap();
},
createMap: function() {
var data = {
'name': this.options.name,
'width': this.options.width,
'height': this.options.height,
'lat': this.lat,
'lng': this.lng,
'zoom': this.zoom
};
var mapOptions = {
zoom: 5,
center: {lat: -25.344, lng: 131.036},
};
var target = 'gmap-'+this.name;
console.log(target);
this.map = new google.maps.Map(document.getElementById(target), mapOptions);
// This code works with 3.34. Initial map is rendered with 3.35, but without buttons and not updated if zooming.
// 3.34
// > gmap-geolocation
// 3.35
// > gmap-geolocation
// > gmap-undefined
// > Uncaught TypeError: Cannot read property 'firstChild' of null js?v=3.35&key=xxx:70
// > gmap-undefined
//this.map = new google.maps.Map(document.getElementById('gmap-geolocation'), mapOptions);
// This code works with 3.34. This code does not work at all with 3.35 - browser freezes.
},
});
{% autoescape off %}
var data = {% firstof value "{}" %};
{% endautoescape %}
data.name = "{{ name }}";
data.width = "{{ width }}";
data.height = "{{ height }}";
new Map($("#geolocation-container"), data);
</script>
编辑.html
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
{% formrow form.geolocation %}
</form>
问题似乎出在小部件.html。再一次,如果整个代码保持不变,并且只有谷歌地图 API 从 3.34 升级到 3.35,我会收到错误"未捕获的类型错误:无法读取 null 的属性'firstChild'"。
我将不胜感激如何解决此问题的任何提示。
已通过将 CanJS 控制函数重命名为"Map"得到解决。如果在小部件中.html
Map = can.Control({
更改为
Map2 = can.Control({
。以及使用 创建的实例
new Map2($("#geolocation-container"), data);
。然后一切在谷歌地图JavaScript API v3.35中再次正常工作。