1

Turbolinks と Google Maps 4 Rails を使用しています。パフォーマンス上の理由から、すべての JavaScript ロードを非同期にしようとしています。

同じ Web サイト内の別のページから移動した場合、マップ ページが正しく読み込まれることがわかりました。しかし、ブラウザに住所を入力してマップ ページに移動すると、次の 2 つのエラーが表示されます。

Uncaught ReferenceError: Gmaps is not defined

Uncaught ReferenceError: jQuery is not defined

これが私のセットアップです:

私の頭の中で(ハムルで)

%script{ src:'//maps.google.com/maps/api/js?v=3.13&sensor=true&libraries=geometry', type:'text/javascript' }
-# http://www.rickypai.com/blog/2013/02/22/web-dev-gotchas-with-rails-4-0-turbolinks/
- if Settings.ASYNC_JAVASCRIPT
    = render 'layouts/async_javascript', path: 'application'
- else
    = javascript_include_tag 'application', data_turbolinks_track: true

_async_javascript.html.erb

<%# http://railscasts.com/episodes/369-client-side-performance?view=asciicast %>
<script type="text/javascript">
    (function() {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.async = true;
        script.src = '<%= j javascript_path(path) %>';
        var other = document.getElementsByTagName('script')[0];
        other.parentNode.insertBefore(script, other);
    }) ();
</script>

アプリケーション.js

//= require modernizr
//= require jquery
//= require jquery.turbolinks
//= require google.maps.infobox
//= require google.maps.richmarker
//= require google.maps.markerclusterer
//= require gmaps/google
...
//= require turbolinks

そして最後に、体内で (ハムルで)

- present @location, LocationPresenter do |p|
    = render 'map_coffee', id: 'l_map', markers: [p.marker].to_json, lat: p.latitude, lng: p.longitude

_map.coffee.html.haml

:coffee
    class RichMarkerBuilder extends Gmaps.Google.Builders.Marker

        create_marker: ->
            options = _.extend @marker_options(), @rich_marker_options()
            @serviceObject = new RichMarker options

        rich_marker_options: ->
            marker = document.createElement 'div'
            marker.setAttribute 'class', 'marker_container'
            marker.innerHTML = @args.marker
            _.extend @marker_options(), { content: marker }

        create_infowindow: ->
            return null unless _.isString @args.infowindow

            boxText = document.createElement 'div'
            boxText.setAttribute 'class', 'infowindow_container'
            console.log @args
            boxText.innerHTML = @args.infowindow
            @infowindow = new InfoBox(@infobox(boxText))

            @bind_infowindow()

        infobox: (boxText)->
            content: boxText
            pixelOffset: new google.maps.Size(0, 0)
            boxStyle:
                width: '280px'


    handler = Gmaps.build 'Google', { builders: { Marker: RichMarkerBuilder }, markers: { maxRandomDistance: null } }

    handler.buildMap
        provider: {}
        internal:
            id: '#{id}'
    , ->
        json = #{markers}
        if json
            markers = handler.addMarkers json
            handler.bounds.extendWith markers
            handler.fitMapToBounds()
            if json.length == 1
                handler.getMap().setZoom #{Settings.LOCATIONS_DEFAULT_ZOOM}
        else
            handler.map.centerOn { lat: #{lat}, lng: #{lng} }
            handler.getMap().setZoom #{Settings.LOCATIONS_DEFAULT_ZOOM}

これを正しく設定する方法を知っている人はいますか?Turbolinks は Rails 4 の標準であるため、これに関する多くのドキュメントがあることは驚くべきことです。どんな助けも大歓迎です!

これにも苦労している人のために、これを行う方法がわかり次第、Gmaps4Rails wiki を更新します!

4

1 に答える 1

2

私が見つけた最善の (そして最もクリーンな) 方法は、javascript をアセット パイプラインに追加することです。これにより、JQuery が使用可能になります。したがって、いくつかのcoffeescriptファイルで次のようになります。

$('#map').mappy()

JQuery プラグイン Mappy を次のように定義する場所:

(($, window) ->

    class Mappy
        # defaults:
        constructor: (el, options) ->
            @$el = $(el)
            # @options = $.extend({}, @defaults, options)

            @id         = @$el.attr 'id'
            @lat        = @$el.data 'lat'
            @lng        = @$el.data 'lng'
            @markers    = @$el.data 'markers'
            @handler    = Gmaps.build 'Google', { builders: { Marker: RichMarkerBuilder }, markers: { maxRandomDistance: null } }

            @handler.buildMap
                provider: {}
                internal:
                    id: @id
            , =>
                json = @markers
                if json
                    markers = @handler.addMarkers json
                    @handler.bounds.extendWith markers
                    @handler.fitMapToBounds()
                    if json.length == 1
                        @handler.getMap().setZoom $.LOCATIONS_DEFAULT_ZOOM
                else
                    @handler.map.centerOn { lat: @lat, lng: @lng }
                    @handler.getMap().setZoom $.LOCATIONS_DEFAULT_ZOOM


    class RichMarkerBuilder extends Gmaps.Google.Builders.Marker

        create_marker: ->
            options = _.extend @marker_options(), @rich_marker_options()
            @serviceObject = new RichMarker options

        rich_marker_options: ->
            marker = document.createElement 'div'
            marker.setAttribute 'class', 'marker_container'
            marker.innerHTML = @args.marker
            _.extend @marker_options(), { content: marker }

        create_infowindow: ->
            return null unless _.isString @args.infowindow

            boxText = document.createElement 'div'
            boxText.setAttribute 'class', 'infowindow_container'
            console.log @args
            boxText.innerHTML = @args.infowindow
            @infowindow = new InfoBox(@infobox(boxText))

            @bind_infowindow()

        infobox: (boxText)->
            content: boxText
            pixelOffset: new google.maps.Size(0, 0)
            boxStyle:
                width: '280px'

    $.fn.extend mappy: (option, args...) ->
        @each ->
            $this = $(this)
            data = $this.data('mappy')

            if !data
                $this.data 'mappy', (data = new Mappy(this, option))

            if typeof option == 'string'
                data[option].apply(data, args)

) window.jQuery, window

次に、haml で次のようなことを実行して、データを利用できるようにします。

- present @location, LocationPresenter do |p|
     #map{ data: {  markers: [p.marker].to_json, lat: p.latitude, lng: p.longitude } }
于 2013-11-12T00:07:21.400 に答える