0

我试图将实例变量从我的 rails 应用程序传递到关联的咖啡脚本文件,但它目前似乎没有被解析。我错过了什么?

位置.js.coffee.erb

$.ajax
  url: "/map_groups/<%= @id %>.json"
  type: "get"
  dataType: "json"
  async: false
  success: (response) ->
    exports.response = response

位置控制器.rb

def index
  @id = (params[:id]) ? params[:id] : 1
  @locations = Location.all
end

但这是控制台中显示的错误:

Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:3000/map_groups/.json

我可以做些什么来解析实例变量吗?

笔记:

我知道变量存在,因为它被传递给视图。

编辑:我想要做什么

我的大部分数据都是通过 JSON 发送的,我创建了一个自定义路由,以便让咖啡脚本知道要提取哪些 json 数据:

get "/locations/map-group/:id", controller: :locations, action: :index, as: :map_group

如果您参考我的控制器 - 您将看到如果用户访问普通的旧/locationsID,则 ID 默认为 1。否则,ID 是 URL 中指定的任何内容。coffeescript 文件需要通过 AJAX 调用提取与该 ID 相关的数据。我怎样才能告诉咖啡脚本那个 ID 是什么?

4

2 回答 2

5

我会做什么

如果可以避免的话,我强烈建议不要使用 Ruby 实例变量来生成 CoffeeScript。我建议使用这样的库来处理您正在考虑的用例:

https://github.com/railsware/js-routes

# Configuration above will create a nice javascript file with Routes object that has all the rails routes available:

Routes.users_path() // => "/users"
Routes.user_path(1) // => "/users/1"
Routes.user_path(1, {format: 'json'}) // => "/users/1.json"
Routes.new_user_project_path(1, {format: 'json'}) // => "/users/1/projects/new.json"
Routes.user_project_path(1,2, {q: 'hello', custom: true}) // => "/users/1/projects/2?q=hello&custom=true"
Routes.user_project_path(1,2, {hello: ['world', 'mars']}) // => "/users/1/projects/2?hello%5B%5D=world&hello%5B%5D=mars"

这加上 HTML5data-*标记将帮助您在 JavaScript 中传递所需的识别信息:

http://html5doctor.com/html5-custom-data-attributes/

例如:

<div id="my_awesome_location" data-location-id="<%= @location.id %>">...</div>

然后像这样加载你的ajax:

id = $("#my_awesome_location").data('location-id')

$.ajax
  url: Routes.map_group_path(id) #=> "/map_groups/#{id}.json"
  type: "get"
  dataType: "json"
  ...

无论如何要怎么做

但是,如果您绝对必须在 CoffeeScript 中使用 ERB 样式标签,您可以使用coffee.erb文件扩展名来实现:

http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets

2.3.3 JavaScript/CoffeeScript 和 ERB

如果您将 erb 扩展添加到 JavaScript 资产,使其类似于 application.js.erb,那么您可以在 JavaScript 代码中使用asset_path 帮助程序:

$('#logo').attr({
  src: "<%= asset_path('logo.png') %>"
});

这将写入被引用的特定资产的路径。

同样,您可以在具有 erb 扩展名的 CoffeeScript 文件中使用asset_path 帮助程序(例如,application.js.coffee.erb):

$('#logo').attr src: "<%= asset_path('logo.png') %>"

为什么你可能不想那样做

我建议使用上述库而不是直接 ERB 的原因是控制器/视图和资产之间的紧密耦合。

这也意味着您必须先预加载整个应用程序,然后才能进行资产编译,因此如果您尝试部署到 Heroku 之类的 PaaS,那么您将在后面受到影响。

https://devcenter.heroku.com/articles/rails-asset-pipeline

在 slug 编译过程中,应用程序的配置变量在环境中不可用。因为必须加载应用程序才能运行 assets:precompile 任务,任何需要存在配置变量的初始化代码都应该优雅地处理 nil 情况。

基本上,如果你稍微改变你的控制器,你就有可能破坏你的资产。最好将它们保持为单独的单元,并引入一个中介层来处理您要解决的问题。

于 2013-10-09T01:52:02.907 回答
1

正如法利奈特所说,是的,你可以,但请不要因为他所说的原因。

对我最有效的是隐藏字段,其中包含我的 ERB 文件中的数据。然后,由于您使用的是 JQuery,因此只需idField.val()在您的 url 中使用即可$.ajax

希望有帮助。

于 2013-10-09T02:05:37.770 回答