新手问题 js.erb 如何在<%= %>里插入 js 变量?

QueXuQ · 2013年12月09日 · 最后由 xds2000 回复于 2013年12月10日 · 5709 次阅读
$("body").append('<img src="assets/the_page_' + $(this).attr("data-name") + '.jpg" />')

因读不到图片,所以这里要使用 erb,就需要:

$("body").append('<img src= "<%= asset_path( 'the_page_xxxx.jpg') %>"  />')

在 xxx 处应该怎么加入 js 代码呢?

这样?

<% file_name = "the_page_#{xxxx}.jpg" %>
$("body").append('<img src="<%= asset_path(file_name) %>" />')

试试这样?$("body").append("<%= image_tag( 'the_page_xxxx.jpg') %>")

#2 楼 @tyaccp_guojian 这个写法不知道可以不可以,但是关键是 xxx,应该是怎么用$(this).attr("data-name")来代替?因为是 js 代码放到<%= %>里。

不能这样做的吧,<%= %> 这个先会在服务器上执行掉,然后渲染返回到浏览器,JS 后执行

你要么把 xxx 通过参数通过 controller 用变量的方式传到 erb 里去

$("body").append('<img src= "<%= asset_path("the_page_#{@xxxx}.jpg") -%>"  />')

$(this).attr("data-name"),直接写$(this).data('name');

看到你用的 append,你应该是想在用户操作的时候动态添加图片到页面中,如果是这样的话,我看你得发个请求去后台拿到图片的 url 再插入,因为你的 js.erb 依赖客户端 JS 的变量;

#6 楼 @tyaccp_guojian #5 楼 @miclle 这么说法,本来一个:

$("body").append('<img src="assets/the_page_' + $(this).attr("data-name") + '.jpg" />')

javascript 很方便处理的问题,被 Asset Pipeline 弄的很复杂。如果不用asset_path就找不到图片,如果实在没有好办法的话,最好的办法估计也就是把图片做成 css 的background-image了吧!

理解能力有点差,楼主要是不介意把需求或要实现的功能说仔细一点,大家再讨论一下或许有比你那个办法更优雅的实现方式

#8 楼 @tyaccp_guojian 我猜 @QueXuQ 你遇到的问题是这样,Asset Pipeline 后 assets 下的 image 文件名都会变掉,所以你没办法在 JS 里预先把代码写好 我能想到的两种办法:

  1. 用 css 去做这件事,把图片定义在 selector 的 background 里面
  2. 把这些需要用到的图片直接放在 public 目录里面

#8 楼 @tyaccp_guojian 我想的和 4 楼想的那样,因为先过 erb 的,所以貌似不好实现。

问题是这样: 在 js 和 css 里不可以直接通过文件地址引入图片,例如/assets/image.jpg因为图片最后的名字是image_asfsafsadasb.jpg会生成一串随机串在后面,这就导致,无法直接在 js 里面查入一个imgtag。因为:

$("body").append('<img src="/assets/image.jpg" />')

这样是读不出图片的,需要:

$("body").append('<img src="<%= asset_path(”image.jpg") />')

所以我想实现一个效果,例如点击就往 body 插入一个图片,而图片的名字是image_a,image_b,image_c而显示 a 还是 b,c,根据我点击的按钮里的data-name属性决定。 所以:

$("body").append('<img src="/assets/image_' + $(this).data('name') + '.jpg" />')

是这样形式来正常展示的。

其实我觉得还可以这样,你直接把 <%= asset_path(file_name) %> 放在 $(this).attr("data-name")的 data-name 属性里面,随页面一起渲染

<button data-name="<%= asset_path(file_name) -%>"></button>

#11 楼 @miclle 这个不错,目测目前这方法最方便了。

问题说白了就是不知道该什么时候渲染和渲染到哪里,如果能在渲染页面的时候就将以后 JS 可能需要的东西都渲染,就可以减少 ajax 请求,如果需要请求的数据是根据用户操作决定的,可能就需要 ajax 了,这么看来楼主的需求属于第一种 @miclle 好办法

你这需求的其实是获取静态文件的文件名,实际不需要任何动态渲染 Asset Pipeline 本身就支持 js.erb……你只需要这样: app/assets/javascript/assets.coffee.erb

# 假设你现在用的js框架没有dependence injection
# 那么只能将着些文件名放在一个全局变量中
@StaticAssets = 
  file_a: <%= asset_path(file_a) %>
  file_b: <%= asset_path(file_b) %>
  # ...(其他文件,或者干脆写个helper生成所以其他需要的文件)

然后现在你这需求就应该就不需要通过服务器了,客户端可以这样弄

fileName = StaticAssets['someFileNameYouAlreadyKnow']
$('<img />').prop('scr', fileName).appendTo($("body"))

如果只是这样选中静态文件的话,可以连 ajax 都省了

#14 楼 @aptx4869 第一次看到这种用法,学习了,后来去查了下,这里有,以前看东西都不是很仔细

使用 js.erb 的方式早就过时了。还是用纯 javascript 的方式吧。后台提供一个 JSON API 供调用

需要 登录 后方可回复, 如果你还没有账号请 注册新账号