Проблема API карт Google с версией 3.35 в виджете поля формы django - PullRequest
0 голосов
/ 07 февраля 2019

У меня проблема с API карт Google после обновления до версии 3.35.Цель состоит в том, чтобы отобразить карту в форме, чтобы пользователь мог определить геолокацию.Я использую Django 1.11.12 и CanJS 2.0.2.

Вот код (уменьшен для простоты), который отлично работает с API карт Google версии 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.Еще раз, если весь код остается прежним, и только API карт Google обновляется с 3.34 до 3.35, я получаю ошибку «Uncaught TypeError: Невозможно прочитать свойство firstChild of null».

Я быцени любой совет, как это исправить.

1 Ответ

0 голосов
/ 11 февраля 2019

Проблема была устранена путем переименования функции управления CanJS «Карта».Если в widget.html

Map = can.Control({

установлено значение

Map2 = can.Control({

... и экземпляр, созданный с помощью

new Map2($("#geolocation-container"), data);

..., тогда все работает нормальноснова с API JavaScript карт Google v3.35.

...