如何在保留参数的同时通过 AJAX 表单将参数传递给 create.js?
How do I pass params through an AJAX form to create.js while retaining the params?
我有一些评论有投票分数,我使用切换键按最近和流行来过滤它们。当我点击流行时,它通过 sort: popular 作为参数,并根据它对评论列表进行排序。然后,当用户 post 使用 AJAX 发表另一条评论时,我试图通过将排序参数通过评论表单传递给控制器,然后到 create.js,它根据传入的参数对评论进行排序。这只工作一次,但一旦我 post 2 条评论,它就会恢复到最近排序,因为我我无法继续传递排序参数。
我的排序开关:
<% if params[:sort] == 'popular' %>
sorted by <%= link_to("Recent", video_path(video), remote: true, class: 'gray-link') %> |
<%= link_to("POPULAR", video_path(video, sort: 'popular'), remote: true, class: 'gray-link') %>
<% else %>
sorted by <%= link_to("RECENT", video_path(video), remote: true, class: 'gray-link') %> |
<%= link_to("Popular", video_path(video, sort: 'popular'), remote: true, class: 'gray-link') %>
<% end %>
评论表单,我将我的参数作为隐藏字段传递给 :sort - 注意,它们是嵌套的评论,因此是 form_for 语法,但它在这里应该无关紧要。
<%= form_for [@video, @comment, , :html => {:class => 'form_height'}], :remote => true, method: :post, url: video_comments_path(@video.id) do |f| %>
<div id="comment-form-errors">
<%= render :partial => "/videos/comment_form_errors" %>
</div>
<%= f.hidden_field :parent_id, :value => parent_id %>
<%= f.hidden_field :sort, value: params[:sort] %>
<%= f.text_area :post, placeholder: 'Comment', id: 'comment-box' %>
<% if parent_id != nil %>
<%= f.submit "Reply" %>
<% else %>
<%= f.submit %>
<% end %>
<% end %>
然后在控制器中我创建了一个变量@sort来从评论表单中收集排序参数:
def create
@comment = @video.comments.build(comment_params)
@comment.user = current_user
@sort = params[:comment][:sort]
respond_to do |format|
if @comment.save
format.html { redirect_to video_path(@video.id), notice: "You said something. Let's hope it didn't suck." }
format.js { }
else
format.html { render 'videos/show', alert: "There was an error." }
format.js {}
end
end
end
然后我根据是否通过了流行的排序参数来对评论进行排序:
<% if @comment.errors.present? %>
$('#comment-form-errors').html("<%= escape_javascript(render(:partial => '/videos/comment_form_errors')) %>");
<% else %>
<% if @sort == 'popular' %>
$('#comment-list').html("<%= j nested_comments (@video.comments).arrange(:order => 'cached_weighted_score DESC') %>");
<% else %>
$('#comment-list').html("<%= j nested_comments (@video.comments).arrange(:order => 'created_at DESC') %>");
<% end %>
$('#review-form-errors').html('');
$('textarea#comment-box').val('');
$('#comment-counter').text("<%= pluralize(@video.comments.count, 'comment') %>");
$('.error-explanation').text('');
<% end %>
问题出在这里:我的服务器日志第一次显示发送的参数为:参数:{"utf8"=>"✓", "comment"=>{"parent_id"= >"321", "sort"=>"popular", "post"=>"c"}, "commit"=>"Reply", "video_id" =>“283”} - 太棒了,我 post 评论和评论,如果按流行排序,则保持按流行排序。
但是如果我 post 连续第二个评论,它不会传递排序参数:参数:{"utf8"=>"✓", "comment"=>{"parent_id"=>"322", "sort"=>"", "post"=>"d"}, "commit"=>"Reply", "video_id" =>"283"} - 我的评论恢复为默认排序,最近。
我不知道从这里到哪里去。我觉得我遗漏了一些小东西,但是四处搜索都找不到解决方案。任何人都可以指出我正确的方向,我真的很感激任何关于如何让它工作的想法,或者如果需要的话,如果有更好的方法来做到这一点,如何修改我的解决方案。
谢谢!
编辑:在 MravAtomski 的帮助下,我得以完成这项工作。我将评论表更改为:
<% if params[:comment] %>
<%= f.hidden_field :sort, value: params[:comment][:sort] %>
<% else %>
<%= f.hidden_field :sort, value: params[:sort] %>
<% end %>
并在我的评论控制器创建操作中添加:
if params[:sort]
@sort = params[:sort]
elsif params[:comment][:sort]
@sort = params[:comment][:sort]
end
我的猜测是,在第一个表单提交后,'sort' 隐藏字段丢失了它的值,因此在下一次提交时不会发送它。
<%= f.hidden_field :sort, value: params[:sort] %>
也许应该
<%= f.hidden_field :sort, value: params[:comment][:sort] %>
因为form_for中正在使用评论对象。
也可能不是这种情况,但请检查它是否在执行 ajax 请求而不是 html 请求。如果它正在执行 html 请求,那么它可能会由于页面刷新而丢失 'sort' 隐藏值。
编辑
所以当页面加载时它使用 params[:sort] 然后在创建提交后它使用 params[:comment][:sort],也许像这样的东西可以用作快速解决方案:
<%= f.hidden_field :sort, value: params[:sort] || params[:comment][:sort] %>
其他解决方案是将数据属性添加到未通过创建 ajax 请求更改的标签之一。即表单标签。将数据排序属性添加到用于创建评论的表单标签:
<%= form_for [@video, @comment, , :html => {:class => 'form_height ..., :data-sort => params[:sort] do |f| %>
创建评论时不要更改数据属性,仅当用户更改排序时才应设置它,并在每次需要排序值时将其作为 ajax 请求参数发送。
我有一些评论有投票分数,我使用切换键按最近和流行来过滤它们。当我点击流行时,它通过 sort: popular 作为参数,并根据它对评论列表进行排序。然后,当用户 post 使用 AJAX 发表另一条评论时,我试图通过将排序参数通过评论表单传递给控制器,然后到 create.js,它根据传入的参数对评论进行排序。这只工作一次,但一旦我 post 2 条评论,它就会恢复到最近排序,因为我我无法继续传递排序参数。
我的排序开关:
<% if params[:sort] == 'popular' %>
sorted by <%= link_to("Recent", video_path(video), remote: true, class: 'gray-link') %> |
<%= link_to("POPULAR", video_path(video, sort: 'popular'), remote: true, class: 'gray-link') %>
<% else %>
sorted by <%= link_to("RECENT", video_path(video), remote: true, class: 'gray-link') %> |
<%= link_to("Popular", video_path(video, sort: 'popular'), remote: true, class: 'gray-link') %>
<% end %>
评论表单,我将我的参数作为隐藏字段传递给 :sort - 注意,它们是嵌套的评论,因此是 form_for 语法,但它在这里应该无关紧要。
<%= form_for [@video, @comment, , :html => {:class => 'form_height'}], :remote => true, method: :post, url: video_comments_path(@video.id) do |f| %>
<div id="comment-form-errors">
<%= render :partial => "/videos/comment_form_errors" %>
</div>
<%= f.hidden_field :parent_id, :value => parent_id %>
<%= f.hidden_field :sort, value: params[:sort] %>
<%= f.text_area :post, placeholder: 'Comment', id: 'comment-box' %>
<% if parent_id != nil %>
<%= f.submit "Reply" %>
<% else %>
<%= f.submit %>
<% end %>
<% end %>
然后在控制器中我创建了一个变量@sort来从评论表单中收集排序参数:
def create
@comment = @video.comments.build(comment_params)
@comment.user = current_user
@sort = params[:comment][:sort]
respond_to do |format|
if @comment.save
format.html { redirect_to video_path(@video.id), notice: "You said something. Let's hope it didn't suck." }
format.js { }
else
format.html { render 'videos/show', alert: "There was an error." }
format.js {}
end
end
end
然后我根据是否通过了流行的排序参数来对评论进行排序:
<% if @comment.errors.present? %>
$('#comment-form-errors').html("<%= escape_javascript(render(:partial => '/videos/comment_form_errors')) %>");
<% else %>
<% if @sort == 'popular' %>
$('#comment-list').html("<%= j nested_comments (@video.comments).arrange(:order => 'cached_weighted_score DESC') %>");
<% else %>
$('#comment-list').html("<%= j nested_comments (@video.comments).arrange(:order => 'created_at DESC') %>");
<% end %>
$('#review-form-errors').html('');
$('textarea#comment-box').val('');
$('#comment-counter').text("<%= pluralize(@video.comments.count, 'comment') %>");
$('.error-explanation').text('');
<% end %>
问题出在这里:我的服务器日志第一次显示发送的参数为:参数:{"utf8"=>"✓", "comment"=>{"parent_id"= >"321", "sort"=>"popular", "post"=>"c"}, "commit"=>"Reply", "video_id" =>“283”} - 太棒了,我 post 评论和评论,如果按流行排序,则保持按流行排序。
但是如果我 post 连续第二个评论,它不会传递排序参数:参数:{"utf8"=>"✓", "comment"=>{"parent_id"=>"322", "sort"=>"", "post"=>"d"}, "commit"=>"Reply", "video_id" =>"283"} - 我的评论恢复为默认排序,最近。
我不知道从这里到哪里去。我觉得我遗漏了一些小东西,但是四处搜索都找不到解决方案。任何人都可以指出我正确的方向,我真的很感激任何关于如何让它工作的想法,或者如果需要的话,如果有更好的方法来做到这一点,如何修改我的解决方案。
谢谢!
编辑:在 MravAtomski 的帮助下,我得以完成这项工作。我将评论表更改为:
<% if params[:comment] %>
<%= f.hidden_field :sort, value: params[:comment][:sort] %>
<% else %>
<%= f.hidden_field :sort, value: params[:sort] %>
<% end %>
并在我的评论控制器创建操作中添加:
if params[:sort]
@sort = params[:sort]
elsif params[:comment][:sort]
@sort = params[:comment][:sort]
end
我的猜测是,在第一个表单提交后,'sort' 隐藏字段丢失了它的值,因此在下一次提交时不会发送它。
<%= f.hidden_field :sort, value: params[:sort] %>
也许应该
<%= f.hidden_field :sort, value: params[:comment][:sort] %>
因为form_for中正在使用评论对象。
也可能不是这种情况,但请检查它是否在执行 ajax 请求而不是 html 请求。如果它正在执行 html 请求,那么它可能会由于页面刷新而丢失 'sort' 隐藏值。
编辑
所以当页面加载时它使用 params[:sort] 然后在创建提交后它使用 params[:comment][:sort],也许像这样的东西可以用作快速解决方案:
<%= f.hidden_field :sort, value: params[:sort] || params[:comment][:sort] %>
其他解决方案是将数据属性添加到未通过创建 ajax 请求更改的标签之一。即表单标签。将数据排序属性添加到用于创建评论的表单标签:
<%= form_for [@video, @comment, , :html => {:class => 'form_height ..., :data-sort => params[:sort] do |f| %>
创建评论时不要更改数据属性,仅当用户更改排序时才应设置它,并在每次需要排序值时将其作为 ajax 请求参数发送。