2012-08-12 11 views
5

私はこの男を理解しようと思っているほど多くのStackOverflow/googleグループを使いました。Google Map API BackBoneJSヌルの 'offsetWidth'プロパティを読み取ることができません

私は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)'の中にマップの内容を入れてみましたか? http://stackoverflow.com/a/9145790/479863 –

+0

これを回答として入れても大丈夫な人はいらないでしょう。 – rpearce

+0

アンダースコアの_にリファクタリングしました。友人の推薦に基づいて機能を延期する。 – rpearce

答えて

7

私はあなたの問題は、あなたがそれにアクセスしようとした後まで#mapCanvasはDOMではないことであることを推測すると思いますそう:

document.getElementById('mapCanvas') 

は役に立たないでしょうnull。あなたはそれを使用する前に#mapCanvasがDOMに入るまで待つ必要があります。あなたは、有効なIDを与えるだろうが、マップが妙にレンダリングされるので、それは大きさを持っていないので、あなたがGoogleマップの機能を混同します

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

:あなたは、このいずれかのような何かを行うことはできません。これは、Google Mapsのものをバインドする前に、すべてがDOMに入るのを待つことに戻ります。この周り

一つの方法は、setTimeout with a delay of zero使用することです。これは、それが仕事をする奇妙なビットに見える

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

、このトリックは、基本的には、ブラウザの作業キューにあなたのrenderMapコールをダンプし、それが一度それを実行している程度取得しますあなたはコントロールをブラウザに戻しました。

また_.deferを使用することができます。現在のコールスタックは、0の遅延でのsetTimeoutを使用するのと同様にクリアするまで機能を呼び出す

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

延期します。 UIスレッドの更新をブロックすることなく、高価な計算やHTMLレンダリングをチャンクで実行する場合に便利です。

これは、あなたの意図を明示するためのより良い選択かもしれません。

+0

あなたは男です。本当にありがとう – rpearce

関連する問題