Google Map API BackBoneJS无法读取null的属性'offsetWidth'

rpe*_*rce 5 javascript google-maps google-maps-api-3 backbone.js

我已经经历了尽可能多的StackOverflow/google小组,因为我可以想象试图找出这个人.

我正在使用BackboneJS来渲染具有起始位置和结束位置的地图.在新的页面/页面刷新,我没有得到这个错误,并且地图和东西工作正常,因为我使用jQuery的$(窗口).load(.....)函数; 然而,当我动态地呈现我的看法,我得到这个错误,我相信,因为DOM没有加载DIV,但(通过document.getElementById失败).我曾尝试比$(窗口).load(其他)的不同方法的所有方式,但我不能得到任何这既适用于用例(新鲜页面加载 - BackboneJS查看加载).尝试在模板不起作用后立即调用该函数.

任何帮助,将不胜感激.

罗伯特

视图:

    App.Views.MapShow = Backbone.View.extend({
      initialize: function() {
        _.bindAll(this, 'render');
        var self = this;
        $(window).load(function() {
          self.renderMap();
        });
      },

      render: function() {
        this.renderTemplate();
      },

      renderTemplate: function() {
        this.$el.html(JST['path/to/show/file']());
      },

      renderMap: function() {
        var from     = this.model.get('location_from');
        var to       = this.model.get('location_to');
        var geocoder = new google.maps.Geocoder();
        var map      = new google.maps.Map(document.getElementById('mapCanvas'), {
          mapTypeId: google.maps.MapTypeId.ROADMAP
        });
        var directionsService = new google.maps.DirectionsService();
        var directionsDisplay = new google.maps.DirectionsRenderer();

        directionsDisplay.setMap(map);

        var request = {
          origin: from,
          destination: to,
          travelMode: google.maps.DirectionsTravelMode.DRIVING
        };

        directionsService.route(request, function(response, status) {
          if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(response);
          }
        });
      }
    });
Run Code Online (Sandbox Code Playgroud)

HTML:

    <div class="map" id="mapCanvas"></div>
Run Code Online (Sandbox Code Playgroud)

mu *_*ort 7

我猜你的问题是#mapCanvas在你尝试访问它之前不在DOM中,所以这个:

document.getElementById('mapCanvas')
Run Code Online (Sandbox Code Playgroud)

会给你一个无用的null.#mapCanvas在使用它之前,您需要等到DOM中; 你不能做这样的事情:

map_canvas = this.$el.find('#mapCanvas')[0];
Run Code Online (Sandbox Code Playgroud)

这将为您提供有效的ID,但您会混淆谷歌地图功能,因为它没有大小,因此地图将被奇怪地渲染.这会让您在绑定Google地图之前等待DOM中的所有内容.

解决这个问题的一种方法是使用setTimeout延迟为零:

var _this = this;
setTimeout(function() { _this.renderMap() }, 0);
Run Code Online (Sandbox Code Playgroud)

这看起来很奇怪它确实有效,这个技巧基本上将你的renderMap调用转储到浏览器的工作队列中,并且一旦你将控制权返回给浏览器它就会运行它.

您还可以使用_.defer:

延缓 _.defer(function, [*arguments])

延迟调用函数直到当前调用堆栈已清除,类似于使用延迟为0的setTimeout.用于在不阻止UI线程更新的情况下以块的形式执行昂贵的计算或HTML呈现.

这可能是一个更好的选择,因为它使您的意图明确.