Rails 在 JS 中添加局部动态嵌套表单
Rails adding dynamically nested form partial with local in JS
我根据用户在我的表单上的操作附加不同的输入。如果用户单击 "list" 单选按钮,我想显示 possibilities
的嵌套输入。我正在尝试使用 cocoon gem 来创建动态输入字段。我的表单如下所示:
<%= form_for([@issue, @question]) do |f| %>
<%= f.label :content %>
<%= f.text_area :content%>
<br>
<%= f.fields_for :answer do |a| %>
<%= a.label "Answer Type :" %>
<br>
<% Answer.answer_type.options.each do |option| %>
<%= a.label option.first %>
<%= a.radio_button :answer_type, option.first, class: "answer_type" %>
<br>
<% end -%>
<div class="question_list"></div>
<% end -%>
<%= f.submit %>
<ul>
<% @question.errors.full_messages.each do |message| %>
<li><%= message%></li>
<% end -%>
</ul>
<% end %>
这是根据用户点击的位置显示不同部分的 JS :
<%= content_for(:after_js) do %>
<script>
$(document).ready(function(){
$(".answer_type").click(function(){
var value = $(this).val();
console.log(value);
if (value == "Yes/no") {
$(".question_list").empty();
$(".question_list").append("<%= j render 'questions/type/yes_no' %>");
}
else if (value == "List") {
$(".question_list").empty();
$(".question_list").append("<%= j render 'questions/type/list', a:a %>");
}
});
})
</script>
<% end -%>
如果用户单击复选框 "list",我将显示需要构建 a
变量的部分:
<%= a.fields_for :possibilities do |possibility| %>
<%= render 'possibilities/possibility_fields', a: possibility%>
<div class="links">
<%= link_to_add_association 'add possibility', a, :possibilities %>
</div>
<% end -%>
问题是js:
else if (value == "List") {
$(".question_list").empty();
$(".question_list").append("<%= j render 'questions/type/list', a:a %>");
触发错误
undefined local variable or method `a' for #<#<Class:0x007fb5d4786568>:0x007fb5d59c2808>
因为我相信a
在读取JS时还没有构建
当用户单击 "list" 单选按钮时,我如何绕过它并动态构建我的嵌套字段?
这里似乎混淆了服务器端渲染和客户端渲染:
- 服务器端渲染发生在您的 rails 应用中。就是这个过程
将你所有的 erb 变成 html 和 javascript.
- 客户端呈现发生在用户的浏览器中。这是浏览器执行 javascript.
时发生的情况
这意味着您无法使用 Javascript 渲染任何 ERB。
更准确地说,当您的 ruby 应用程序尝试呈现 $(".question_list").append("<%= j render 'questions/type/list', a:a %>");
时,它会尝试在将响应发送给客户端之前立即呈现部分内容。由于 a
变量仅在您的 <%= f.fields_for :answer do |a| %>
块中定义,因此它会引发您看到的错误。
最重要的是,要在客户端进行一些真正的渲染,您可能需要一个渲染库,例如 ReactJS。
我根据用户在我的表单上的操作附加不同的输入。如果用户单击 "list" 单选按钮,我想显示 possibilities
的嵌套输入。我正在尝试使用 cocoon gem 来创建动态输入字段。我的表单如下所示:
<%= form_for([@issue, @question]) do |f| %>
<%= f.label :content %>
<%= f.text_area :content%>
<br>
<%= f.fields_for :answer do |a| %>
<%= a.label "Answer Type :" %>
<br>
<% Answer.answer_type.options.each do |option| %>
<%= a.label option.first %>
<%= a.radio_button :answer_type, option.first, class: "answer_type" %>
<br>
<% end -%>
<div class="question_list"></div>
<% end -%>
<%= f.submit %>
<ul>
<% @question.errors.full_messages.each do |message| %>
<li><%= message%></li>
<% end -%>
</ul>
<% end %>
这是根据用户点击的位置显示不同部分的 JS :
<%= content_for(:after_js) do %>
<script>
$(document).ready(function(){
$(".answer_type").click(function(){
var value = $(this).val();
console.log(value);
if (value == "Yes/no") {
$(".question_list").empty();
$(".question_list").append("<%= j render 'questions/type/yes_no' %>");
}
else if (value == "List") {
$(".question_list").empty();
$(".question_list").append("<%= j render 'questions/type/list', a:a %>");
}
});
})
</script>
<% end -%>
如果用户单击复选框 "list",我将显示需要构建 a
变量的部分:
<%= a.fields_for :possibilities do |possibility| %>
<%= render 'possibilities/possibility_fields', a: possibility%>
<div class="links">
<%= link_to_add_association 'add possibility', a, :possibilities %>
</div>
<% end -%>
问题是js:
else if (value == "List") {
$(".question_list").empty();
$(".question_list").append("<%= j render 'questions/type/list', a:a %>");
触发错误
undefined local variable or method `a' for #<#<Class:0x007fb5d4786568>:0x007fb5d59c2808>
因为我相信a
在读取JS时还没有构建
当用户单击 "list" 单选按钮时,我如何绕过它并动态构建我的嵌套字段?
这里似乎混淆了服务器端渲染和客户端渲染:
- 服务器端渲染发生在您的 rails 应用中。就是这个过程 将你所有的 erb 变成 html 和 javascript.
- 客户端呈现发生在用户的浏览器中。这是浏览器执行 javascript. 时发生的情况
这意味着您无法使用 Javascript 渲染任何 ERB。
更准确地说,当您的 ruby 应用程序尝试呈现 $(".question_list").append("<%= j render 'questions/type/list', a:a %>");
时,它会尝试在将响应发送给客户端之前立即呈现部分内容。由于 a
变量仅在您的 <%= f.fields_for :answer do |a| %>
块中定义,因此它会引发您看到的错误。
最重要的是,要在客户端进行一些真正的渲染,您可能需要一个渲染库,例如 ReactJS。