首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在rails 4中将模型数据嵌入javascript变量时出错

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

Stack Overflow用户
提问于 2015-11-22 14:56:43
回答 1查看 61关注 0票数 1

我很难把JSON中的数据解析成rails。

无论如何,我正在尝试创建标记并将其显示到google地图中,但我一直收到以下语法错误

代码语言:javascript
复制
syntax error, unexpected ')'
...e_javascript raw '@job_json' -).to_s); _erbout.concat "\";\n"

map.js.erb

代码语言:javascript
复制
$(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

代码语言:javascript
复制
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
  ...
EN

回答 1

Stack Overflow用户

发布于 2015-11-23 06:47:21

资源管道(即app/assets文件夹)中的文件不能像视图那样访问控制器中定义的实例变量。这就是你得到一个错误的原因。您必须找到其他方法将@job_json从Rails转换为JavaScript。

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

show.html.erb

代码语言:javascript
复制
...

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

...

maps.js.erb

代码语言:javascript
复制
...

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

...

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

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

更新

我浏览了您的应用程序、Google Maps for Rails README和整个web,发现了一种可能适合您的方法,因为您一次显示多个作业。我自己在你的代码中实现了它,虽然它可能需要一些调整才能达到你喜欢的效果,但它是功能强大的。

第1步:安装地理编码器

Geocoder gem与Google Maps for Rails配对良好,因为它将地址或地名转换为坐标。Google Maps for Rails曾经拥有自己的这一功能,但在这条线上的某个地方它被forfeited the responsibility了。

Gemfile

代码语言:javascript
复制
...

gem 'geocoder'

...

控制台

代码语言:javascript
复制
$ bundle install
$ rails generate migration AddLatitudeAndLongitudeToJobs latitude:float longitude:float
$ rake db:migrate

Job.rb

代码语言:javascript
复制
class Job < ActiveRecord::Base

  geocoded_by :location

  ...

  after_validation :geocode
end

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

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

控制台

代码语言:javascript
复制
$ rake db:schema:load
$ rake db:seed

第3步:在作业show页面上运行地图

jobs_controller.rb

代码语言:javascript
复制
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-executing函数替换为可调用的函数...

maps.js.erb

代码语言:javascript
复制
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());
            }
      });
}

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

show.html.erb

代码语言:javascript
复制
<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

代码语言:javascript
复制
...

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

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

...

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33852428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档