js 生成了一个数组,我现在想把这个数组传到 erb 中。。要怎么做呢? 我的最终目的是根据这个数组生成一个表单
aArray = [1,2,3,4]
$("#player_role").append("<%= escape_javascript( render 'games/player_role' ,:player => aArray) %>");
这样是错误的。。但是
aArray = [1,2,3,4]
$("#player_role").append("<%= escape_javascript( render 'games/player_role' ,:player => [1,2,3,4]) %>");
这样能传递过去。。说明可以传递数组。
楼主没有理解渲染的机制。erb 是服务器端渲染的模板,渲染后的 HTML 下载到浏览器,浏览器才开始渲染 HTML 跟解析 js。你这种问题是倒过来的流程了,怎么可能实现呢?或者你用 ajax 的方式,先得到一个 javascript 数组,然后通过 ajax 请求将数组作为参数提交给后端,后端按照你给的参数渲染 HTML 片段,你再用 js 将这个片段替换到你想替换的位置。
#2 楼 @zix 没有。这个问题本身不复杂也不深奥,是你没有理清楚一个请求的生命历程而已,混淆了其中的区别而已。感觉楼主需要好好阅读一下 《一次完整的 HTTP 事务是怎样一个过程?》这样的文章。
<%= form_for(:player) do |f| %>
<%= f.label :sum_player, "游戏人数"%>
<%= f.number_field :sum_player, in: 1..12, class: 'form-control',id:"sumofplayer" %>
<% end %>
<button type="button" id="myButton" class="btn btn-primary" >
分配角色
</button>
<p>
<%= link_to "A post", playerrole_path, remote: true ,method: :post,class: "btn btn-primary"%>
</p>
<div id="player_role">
</div>
点击按钮后 触发
def test
respond_to do |format|
format.js{}
end
end
所以有一个 test.js.coffee.erb 文件,在其中计算生成数组:根据输入的数字,随机选两个人做坏人。我想根据这个数组反过来再 append 一个表单
arr = []
gRandomArr = ( arr, num_of_badman ) ->
arr.sort ->
return Math.random() - 0.5
for x in arr[0...num_of_badman]
arr[x] = 'badman'
make_role_for_players = (content,num_of_badman) ->
$('#player_role').html('');
if content
for num in [0...content]
arr.push( num )
gRandomArr(arr,num_of_badman)
for x,index in arr
$('#player_role').append('<p>' + index + (if arr[index] == 'badman' then '内奸' else '') + '</p>');
$('#player_role').append('<button type="button" id="myButton" class="btn btn-primary" >
确定角色
</button>');
make_role_for_players $('#sumofplayer').val(),2
<% updated_list = escape_javascript(render 'games/player_role',:player => [1,'bandman',3,4])%>
$("#player_role").append("<%= updated_list%>");
简单重构可以是以下这样的,我假设你渲染的页面是 app/views/players.html.erb
:
<!-- app/views/players.html.erb -->
<%= form_for(:player) do |f| %>
<%= f.label :sum_player, "游戏人数"%>
<%= f.number_field :sum_player, in: 1..12, class: 'form-control',id:"sumofplayer" %>
<% end %>
<button type="button" id="myButton" class="btn btn-primary" >分配角色</button>
<!-- 这个地方的代码可以去掉
<p>
<%= link_to "A post", playerrole_path, remote: true ,method: :post,class: "btn btn-primary"%>
</p>
-->
<div id="role-container">
<div id="player_role"></div>
<!-- 这个按钮固定就好了,没必要像原来一样动态添加 -->
<button type="button" id="myButton" class="btn btn-primary" >确定角色</button>
</div>
<script>
// 全局变量命名空间
App ||= {};
// 这里预先加载角色相关信息,以供后边脚本使用
App.playerRoles = <%== render 'games/player_role', :player => [1,'bandman',3,4] %>;
</script>
而跟这个页面配套的脚本应该是同时下载的,里边的内容改为:
$ ->
$playerCountInput = $('#sumofplayer')
if $playerCountInput.length
badManNumber = 2
$playerRole = $('#player_role')
gRandomArr = ( arr, num_of_badman ) ->
for i in [0...num_of_badman]
# 直接用随机下标就可以了,原来的方式还得整个数组重新排序,没必要
randomIndex = parseInt(Math.random() * arr.length)
arr[randomIndex] = 'badman'
make_role_for_players = (content, num_of_badman) ->
arr = [] # arr 的初始化放在函数里就好了,没必要放外边
$playerRole.empty(); # 用 $.fn.empty() 方法更语义化,比起 $.fn.html("") 更舒服
if content
for num in [0...content]
arr.push( num )
gRandomArr(arr, num_of_badman)
for x,index in arr
$playerRole.append('<p>' + index + (if arr[index] == 'badman' then '内奸' else '') + '</p>');
$playerCountInput.on "change", (e)->
make_role_for_players $playerCountInput.val(), badManNumber
整个过程就没有任何需要往后端发送请求的必要,以上代码仅为示例,我没法运行,你自己看看吧。还不明白的话,就只能奉劝楼主老老实实重新认真学习基础知识了。