【问题标题】:How do I pass params through an AJAX form to create.js while retaining the params?如何在保留参数的同时通过 AJAX 表单将参数传递给 create.js?
【发布时间】:2015-05-15 20:22:33
【问题描述】:

我有一些有投票分数的 cmets,我使用切换按最近和流行过滤它们。当我单击流行时,它会通过 sort: Popular 作为参数,并基于此对评论列表进行排序。然后,当用户使用 AJAX 发布另一条评论时,我试图通过将排序参数通过评论表单传递给控制器​​来保持 cmets 按流行排序(而不是恢复到默认的最近),然后再传递给 create.js,它根据传入的参数对 cme​​ts 进行排序。这一次有效,但一旦我发布 2 个 cmets,它就会恢复为按最近排序,因为我无法继续传递排序参数。

我的排序切换:

<% 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 %>

cmets 表单,我将参数作为隐藏字段传递给 :sort - 注意,它们是嵌套的 cmets,因此是 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

然后我根据流行的排序参数是否通过对 cme​​ts 进行排序:

<% 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"} - 太好了,我发表评论和 cmets,如果按排序热门,按热门排序。

但如果我连续发表第二条评论,它不会传递排序参数: 参数:{"utf8"=>"✓", "comment"=>{"parent_id"=>"322", "sort"= >"", "post"=>"d"}, "commit"=>"Reply", "video_id"=>"283"} - 我的 cmets 恢复为默认排序,最近。

我不知道从这里去哪里。我觉得我错过了一些小东西,但是没有多少搜索找到解决方案。谁能指出我正确的方向,我非常感谢有关如何使其工作的任何想法,或者如果需要,如果有更好的方法可以重新设计我的解决方案。

谢谢!

编辑:在 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

【问题讨论】:

    标签: ruby-on-rails ajax params


    【解决方案1】:

    我的猜测是,在第一个表单提交后,“排序”隐藏字段失去了它的值,所以它不会在下次提交时发送。

    <%= f.hidden_field :sort, value: params[:sort] %>
    

    也许应该是

    <%= f.hidden_field :sort, value: params[:comment][:sort] %>
    

    因为在 form_for 中使用了一个评论对象。

    这可能不是这种情况,但请检查它是否正在执行 ajax 请求而不是 html 请求。如果它正在执行 html 请求,那么它可能会由于页面刷新而丢失“排序”隐藏值。

    编辑

    所以当页面加载时它使用 params[:sort] 然后在创建提交后它使用 params[:comment][:sort],也许这样的东西可以用作快速解决方案:

    <%= f.hidden_field :sort, value: params[:sort] || params[:comment][:sort] %>
    

    其他解决方案是将数据属性添加到未通过创建 ajax 请求更改的标签之一。即表单标签。为用于创建 cmets 的表单标签添加数据排序属性:

    <%= form_for [@video, @comment, , :html => {:class => 'form_height ..., :data-sort => params[:sort] do |f| %>
    

    评论创建时不要改变数据属性,只有在用户改变排序时才设置,每次需要排序值时作为ajax请求参数发送。

    【讨论】:

    • 感谢您的回复,非常感谢!我同意我认为问题是在第一次提交表单后,排序隐藏字段失去了它的价值。我尝试了 params[:comment][:sort] 并为 nil:NilClass 获取了未定义的方法 `[]'。我认为我只想在我第一次提交评论后才使用 params[:comment][:sort],但我想在第一次提交表单时使用 params[:sort] (因此我收到错误消息的原因- 第一次评论提交没有评论参数)。我不确定如何促进这一点,或者它是否正确 - 还有其他想法吗?绝对是 AJAX 提交。
    • 我成功了!非常感谢Mrav - 我希望我能支持你,但显然我还没有足够的声誉。使用 给了我一个错误,但我意识到这是因为 params[:comment] 还不存在,所以在我的表单中我将隐藏的 :sort 值设置为 params[:comment][ :sort] 如果 params[:comment] 存在,否则,将其设置为 params[:sort],然后在我的创建操作中执行相同操作。刚刚更新了我的问题以反映这个解决方案。再次感谢您的帮助!
    猜你喜欢
    • 2015-04-02
    • 1970-01-01
    • 2017-04-14
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    相关资源
    最近更新 更多