5

私はこの男を理解しようと想像できる限り多くのStackOverflow/googleグループを経験してきました。

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>
4

1 に答える 1

7

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

document.getElementById('mapCanvas')

あなたに役に立たないでしょうnull#mapCanvasDOMに入るまで待ってから使用する必要があります。あなたもこのようなことをすることはできません:

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

これで有効なIDが得られますが、サイズがないためにマップが奇妙にレンダリングされるため、Googleマップの機能が混乱します。これにより、Googleマップのものをバインドする前に、すべてがDOMにあるのを待つことに戻ります。

これを回避する1つの方法はsetTimeout、遅延をゼロにして使用することです。

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

これは少し奇妙に見えますが、このトリックは基本的にrenderMap呼び出しをブラウザーの作業キューにダンプし、ブラウザーに制御を戻すと実行に戻ります。

また、使用することができます_.defer

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

現在の呼び出しスタックがクリアされるまで関数の呼び出しを延期します。これは、遅延0でsetTimeoutを使用する場合と同様です。UIスレッドの更新をブロックせずに、コストのかかる計算やHTMLレンダリングをチャンクで実行する場合に便利です。

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

于 2012-08-12T23:05:18.607 に答える