2012-08-12 1 views
5

Я прошел через столько групп StackOverflow/google, сколько могу себе представить, пытаясь понять этого парня.API Google Map API BackBoneJS Невозможно прочитать свойство offsetWidth null

Я использую BackboneJS для рендеринга карты, которая имеет начальное местоположение и конечное местоположение. На новой странице/обновлении страницы я не получаю эту ошибку, и карта и все работают нормально, поскольку я использую функцию jQuery $ (window) .load (.....); однако, когда я динамически визуализую свой вид, я получаю эту ошибку, я полагаю, потому что DOM еще не загрузил DIV (сбой с document.getElementById). Я пробовал всевозможные методы, отличные от $ (window) .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); 
      } 
     }); 
     } 
    }); 

HTML:

<div class="map" id="mapCanvas"></div> 
+0

Вы пытались помещать материал карты в 'setTimeout (function() {...}, 0)' call? http://stackoverflow.com/a/9145790/479863 –

+0

Если вы не возражаете, чтобы это было ответом, это было бы здорово. Исправлено: – rpearce

+0

Реф.функция отсрочки основана на рекомендации друга. – rpearce

ответ

7

Я предполагаю, что ваша проблема в том, что #mapCanvas не является в DOM, пока вы пытаетесь получить к нему доступ так это:

document.getElementById('mapCanvas') 

предоставит вам бесполезный null. Вам нужно подождать, пока #mapCanvas не появится в DOM перед его использованием; Вы не можете сделать что-то вроде этого либо:

map_canvas = this.$el.find('#mapCanvas')[0]; 

Это даст вам действительное удостоверение личности, но вы будете путать функции Google Maps, поскольку он не будет иметь размер, так что карта будет оказана странно. Это вернет вас к ожиданию того, что все будет в DOM, прежде чем связывать ваши данные в Google Maps.

Один из способов заключается в использовании setTimeout with a delay of zero:

var _this = this; 
setTimeout(function() { _this.renderMap() }, 0); 

Это выглядит странно немного, что делает работу, этот трюк в основном сбрасывает свой renderMap вызов в очередь работы браузера и он будет получать вокруг его выполнения раз вы вернули управление браузеру.

Вы также можете использовать _.defer:

Defer_.defer(function, [*arguments])

Задерживает не Призывая функцию до текущего стека вызовов освобождались, аналогичен использованию SetTimeout с задержкой 0. Полезно для выполнения дорогостоящих вычислений или рендеринга HTML в кусках без блокировки потока пользовательского интерфейса от обновления.

Это может быть лучший выбор, поскольку он делает ваше намерение явным.

+0

ты мужчина. Огромное спасибо – rpearce

Смежные вопросы