javascript - 将模型数据嵌入到 Rails 4 中的 JavaScript 变量中时出错

标签 javascript ruby-on-rails google-maps-api-3 google-maps-markers

我在尝试将 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
  ...

最佳答案

Assets 管道中的文件(即 app/assets 文件夹中)无法像 View 那样访问 Controller 中定义的实例变量。这就是您收到错误的原因。您必须找到其他方法将 @job_json 从 Rails 转换为 JavaScript。

由于您只想获取有关单个作业的信息,因此您可以考虑将其作为数据属性包含在页面中的某个位置,如下所示:

show.html.erb

...

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

...

ma​​ps.js.erb

...

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

...

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

您还可以考虑查看 Gon gem,它使您的 Ruby 变量可用于您的 JavaScript Assets 。

<小时/>

更新

我已经浏览了您的申请,Google Maps for Rails README以及整个网络,并找到了一种可能适合您的方法,因为您要同时显示许多职位。我自己在您的代码中实现了它,虽然它可能需要一些调整才能达到您喜欢的方式,但它是实用的。

第 1 步:安装地理编码器

Geocoder gem 与 Google Maps for Rails 完美搭配,因为它将地址或地名转换为坐标。 Google Maps for Rails 过去曾经单独拥有此功能,但在某个时候它 forfeited the responsibility .

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 步:让 map 在作业 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 执行函数替换为可调用函数...

ma​​ps.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());
            }
      });
}

...然后从您的 View 中调用它,您可以在其中访问 Controller 的实例变量。

show.html.erb

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

...

第 4 步:让 map 在用户 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>

...

希望这对您有帮助。正如我提到的,当我尝试时它起作用了,而且我相信我涵盖了我更改的所有内容......

关于javascript - 将模型数据嵌入到 Rails 4 中的 JavaScript 变量中时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33852428/

相关文章:

twitter-bootstrap - 打印时谷歌地图 Canvas 变得空白(Ctrl + P)

javascript - 如何渲染 d3.layout.tree 使其向下传播(根在顶部)

javascript - 来自表单输入的 Reactjs setState 问题

css - 如何在 ruby​​ on rails 上基于 Bootstrap 的导航栏中显示图像

ruby-on-rails - 在 Ubuntu VPS 上单独运行 RoR

javascript - Google Map API V3 - 添加 KML 层时 map "whites out"

javascript - Math.sqrt() 返回无穷大?

javascript - 防止 KeyboardAvoidingView 导致内容重叠(React Native)?

ruby-on-rails - 亚马逊 s3 - ruby 。获取刚刚上传的资源的URL

google-maps - 折线 Google Maps V3 中的文本