如何在保留参数的同时通过 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 请求参数发送。