是否可以解析咖啡脚本资产文件中的Ruby实例变量?

dre*_*att 0 javascript ruby-on-rails coffeescript

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

locations.js.coffee.erb

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

locations_controller.rb

def index
  @id = (params[:id]) ? params[:id] : 1
  @locations = Location.all
end
Run Code Online (Sandbox Code Playgroud)

但这是控制台中出现的错误:

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

有什么办法可以让实例变量解析吗?

注意:

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

编辑:我想做什么

我的大多数数据都是通过JSON发送的,我创建了一个自定义路由,以便让coffeescript知道要提取的json数据:

get "/locations/map-group/:id", controller: :locations, action: :index, as: :map_group
Run Code Online (Sandbox Code Playgroud)

如果您返回我的控制器 - 您将看到如果用户访问普通旧/locationsID,则默认为1.否则,id是URL中指定的内容.coffeescript文件需要通过AJAX调用提取与该ID相关的数据.我如何告诉咖啡因该ID是什么?

Far*_*ght 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"
Run Code Online (Sandbox Code Playgroud)

这个加上HTML5 data-*标签可以帮助您传递JavaScript中所需的识别信息:

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

例如:

<div id="my_awesome_location" data-location-id="<%= @location.id %>">...</div>
Run Code Online (Sandbox Code Playgroud)

然后像这样加载你的ajax:

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

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

怎么办呢

但是,如果您必须在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') %>"
});
Run Code Online (Sandbox Code Playgroud)

这会将路径写入要引用的特定资产.

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

$('#logo').attr src: "<%= asset_path('logo.png') %>"
Run Code Online (Sandbox Code Playgroud)

为什么你可能不想这样做

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

这也意味着你必须预先加载你的整个应用程序才能进行资产编译,所以如果你尝试部署到像Heroku这样的PaaS,你就会在后面咬你.

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

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

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