Google 映射 API 版本 3.35 在 django 表单字段小部件中的问题
Google maps API issue with version 3.35 in a django form field widget
我在将 Google 地图 API 升级到版本 3.35 后遇到问题。目标是以一种形式显示地图,以便用户可以定义地理位置。我正在使用 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)
maps/models.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)
maps/forms.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)
widget.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>
edit.html
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
{% formrow form.geolocation %}
</form>
问题似乎出在 widget.html。再一次,如果整个代码保持不变,只有 Google 映射 API 从 3.34 升级到 3.35,我会得到错误 "Uncaught TypeError: Cannot read property 'firstChild' of null".
如果有任何解决此问题的提示,我将不胜感激。
已通过重命名 CanJS 控制函数 "Map" 解决了该问题。
如果在 widget.html
Map = can.Control({
改为
Map2 = can.Control({
... 以及使用
创建的实例
new Map2($("#geolocation-container"), data);
... 然后使用 Google 地图 javascript API v3.35.
一切正常
我在将 Google 地图 API 升级到版本 3.35 后遇到问题。目标是以一种形式显示地图,以便用户可以定义地理位置。我正在使用 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)
maps/models.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)
maps/forms.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)
widget.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>
edit.html
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
{% formrow form.geolocation %}
</form>
问题似乎出在 widget.html。再一次,如果整个代码保持不变,只有 Google 映射 API 从 3.34 升级到 3.35,我会得到错误 "Uncaught TypeError: Cannot read property 'firstChild' of null".
如果有任何解决此问题的提示,我将不胜感激。
已通过重命名 CanJS 控制函数 "Map" 解决了该问题。 如果在 widget.html
Map = can.Control({
改为
Map2 = can.Control({
... 以及使用
创建的实例new Map2($("#geolocation-container"), data);
... 然后使用 Google 地图 javascript API v3.35.
一切正常