将模型数据嵌入rails 4中的javascript变量时出错



我很难将JSON中的数据解析到rails中。

无论如何,我试图在谷歌地图中创建和显示标记,但我一直收到以下语法错误

syntax error, unexpected ')'
...e_javascript raw '@job_json' -).to_s); _erbout.concat "";n"

map.js.erb

$(document).ready(function() {
  var mapEl = $('#map');
  var optimized = !mapEl.data('test-env');
  handler = Gmaps.build('Google');
  handler.buildMap({
    provider: {
      disableDefaultUI: false
    },
    internal: {
      id: 'map'
    }
  },
  function() {
    var jobJSON = "<%= escape_javascript raw @job_json -%>"; // ERROR MESSAGE HERE
    markers = handler.addMarkers([
      {
        // "lat": 50.827016,
        // "lng": 4.372516,
        "address": 'job.location', // data I want to display on the map
      }
    ], { optimized: optimized }); // true or false
    handler.bounds.extendWith(markers);
    handler.map.centerOn({
      lat: 50.1351162,
      lng: 2.8922343
    });
    handler.getMap().setZoom(6);
    if(!optimized) {
      // Add container for the markers for easy iteration
      // by doing $("#markers img").
      var myOverlay = new google.maps.OverlayView();
      myOverlay.draw = function () {
        this.getPanes().markerLayer.id = 'markers';
      };
      myOverlay.setMap(handler.getMap());
    }
  });
});

代码JobsController

class JobsController < ApplicationController
  before_action :set_job, only: [:edit, :update]
  def index
    @user = User.find(params[:user_id])
    @jobs = Job.all
    # @jobs = current_user.jobs.all
  end
  def show
    @user = User.find(params[:user_id])
    @job = Job.find(params[:id])
    @job_json = @job.to_json(only: [:location, :title, :id])
  end
  def new
    @jobs = Job.new
  end
  def create
    @user = User.find(params[:user_id])
    @job = current_user.jobs.build(job_params)
    @job.user = current_user
    respond_to do |format|
      if @job.save
        format.html { redirect_to @job, success: 'Job wiki was created!' }
        format.json { render json: @job, status: :created, location: @job }
        format.js
      else
        format.html { render action: 'new' }
        format.json { render json: @job.errors, status: :unprocessable_entity }
        format.js
      end
    end
  end
  ...

资产管道(即app/assets文件夹)中的文件无法像视图那样访问控制器中定义的实例变量。这就是为什么会出现错误。您必须找到一些其他方法来将@job_json从Rails转换为JavaScript。

由于您只想获得一份工作的信息,您可以考虑将其作为数据属性包含在页面中的某个位置,如下所示:

show.html.erb

...
<div id='map' data-job='<%= @job_json %>'>
</div>
...

maps.js.erb

...
var jobJSON = $('#map').data('job');
...

显然,如果您需要将大量记录传输到JavaScript,这将不会很好地工作,因为这需要大量的数据属性(或一个长属性)。在这种情况下,AJAX可能会为您提供更好的服务。但只有一条记录,这种方法效果很好。

您还可以考虑研究Gon-gem,它使您的Ruby变量可用于JavaScript资产。


更新

我浏览了你的应用程序,谷歌地图Rails自述,以及整个网络,发现了一种可能适用于你的方法,因为你同时显示了很多工作。我自己在你的代码中实现了它,虽然它可能需要一些调整才能达到你喜欢的效果,但它是功能性的。

步骤1:安装Geocoder

Geocoder gem与GoogleMapsforRails配合得很好,因为它可以将地址或地名转换为坐标。Google Maps for Rails过去有自己的功能,但在这一过程中,它失去了责任。

Gemfile

...
gem 'geocoder'
...

控制台

$ bundle install
$ rails generate migration AddLatitudeAndLongitudeToJobs latitude:float longitude:float
$ rake db:migrate

作业.rb

class Job < ActiveRecord::Base
  geocoded_by :location
  ...
  after_validation :geocode
end

步骤2:重新设定数据库种子

jobs表现在有纬度和经度列,但它们是空的。让after_validation :geocode回调来填充它们的最快方法是用一个干净的数据库覆盖当前数据并重新播种。您可能需要先在seeds.rb中修复您的种子代码;由于缺少逗号和无效的日期时间,它给了我错误。

控制台

$ rake db:schema:load
$ rake db:seed

步骤3:在作业show页面上获取正在工作的地图

jobs_controller.rb

def show
  @user = User.find(params[:user_id])
  @job = Job.find(params[:id])
  @hash = Gmaps4rails.build_markers(@job) do |job, marker|
    marker.lat job.latitude
    marker.lng job.longitude
    marker.infowindow job.location
  end
end

在JavaScript中,将$(document).ready-执行函数替换为可调用函数。。。

maps.js.erb

function drawMap(mapId, marker_json) {
    var mapEl = $('#' + mapId);
    var optimized = !mapEl.data('test-env');
    handler = Gmaps.build('Google');
    handler.buildMap(
        {
            provider: {
                disableDefaultUI: false
            },
            internal: {
                id: 'map'
            }
        },
        function() {
            markers = handler.addMarkers(
                marker_json,
                { optimized: optimized } // true or false
            );
            handler.bounds.extendWith(markers);
            handler.fitMapToBounds();
            if (!optimized) {
                // Add container for the markers for easy iteration
                // by doing $('#markers img').
                var myOverlay = new google.maps.OverlayView();
                myOverlay.draw = function () {
                    this.getPanes().markerLayer.id = 'markers';
                };
                myOverlay.setMap(handler.getMap());
            }
      });
}

然后从视图中调用它,可以访问控制器的实例变量。

show.html.erb

<script type='text/javascript'>
  function initialize() {
      drawMap('map', <%= raw @hash.to_json %>);
  }
  google.maps.event.addDomListener(window, 'load', initialize);
</script>
...

步骤4:获取用户show页面上的地图

这与步骤3基本相同,但有多个作业。

users_controller.rb

...
def show
  @user = User.find(params[:id])
  @jobs = @user.jobs
  @hash = Gmaps4rails.build_markers(@jobs) do |job, marker|
    marker.lat job.latitude
    marker.lng job.longitude
    marker.infowindow job.location
  end
end
...

show.html.erb

<script type='text/javascript'>
  function initialize() {
      drawMap('map', <%= raw @hash.to_json %>);
  }
  google.maps.event.addDomListener(window, 'load', initialize);
</script>
...

我希望这对你有帮助。正如我所提到的,当我尝试它时,它起了作用,我相信我涵盖了我改变的一切。。。

最新更新