[英]How to do Turbolinks + Gmaps4Rails 2?
我正在使用Turbolinks和Google Maps 4 Rails。 出于性能原因,我正在尝试使所有javascript异步加载。
如果我来自同一网站内的另一个页面,我发现地图页面正确加载。 但是,如果我只是在浏览器中输入地址并转到地图页面,则会出现两个错误:
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>
的application.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!
我发现的最好方法(也是最简洁的方法)是将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 } }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.