如何使用 AJAX 重新加载与 Rails 控制器操作无关的页面部分

问题描述

我的网络应用遵循前面问题 herehere 中描述的结构。

界面见下图。

我想要的是,当用户通过 switch 图标(自动提交按钮)编辑/更新验证时,还描述了 here,包含验证/补丁图标的 div 应该重新加载/刷新以更新已验证的翻译。

我可以在一个字段中包含所有这些元素,但只有 moderator: true 用户可以访问 create,并且只有审核特定翻译的版主才能edit and update review

我尝试的是拥有

# entries/index.html.erb
<% @entries.each do |entry| %>
  ...

  <span id="show-review-<%= entry.id %>">
    <%= render 'reviews/show',entry: entry %>
  </span>

  ...

  <% if current_user.moderator %> # and other conditions
    <div id="edit-review-form-<%= entry.id %>">
      <%= render 'reviews/edit',entry: entry %>
    </div>
  <% end %>

  ...
<% end %>
# reviews/_show.html.erb
# Simply if the review exists and if its true
<% if entry.review and entry.review.verified == true %>
  # blue verify icon
<% else %>
  # gray vefify icon
<% end %>
# reviews/_edit.html.erb
<%= form_for([entry,entry.review],remote: true,:authenticity_token => true) do |f| %>
   ...
<% end %>
# reviews/edit.js.erb
$('show-review-<%= entry.id %>')[0].html("<%=j render 'reviews/show',entry: entry %>")

问题:当我提交编辑表单,并且执行控制器中的update动作时,我想重新加载show的部分。如果我有这样的控制器...

def update
  if @entry.review.update!(review_params)
    respond_to do |format|
      format.html { render :partial => "reviews/show",:layout => false }
      format.js { render :template => "reviews/edit",:layout => false }
    end
  end
end

有了这个,在 update,我的网站会重定向评论 URL http://localhost:3000/entries/entry:id/reviews/review:id

这是一个嵌套的模型。为什么只是部分重定向show

# rake routes
entry_reviews     GET    /entries/:entry_id/reviews(.:format)             reviews#index
                  POST   /entries/:entry_id/reviews(.:format)             reviews#create
new_entry_review  GET    /entries/:entry_id/reviews/new(.:format)         reviews#new
edit_entry_review GET    /entries/:entry_id/reviews/:id/edit(.:format)    reviews#edit
entry_review      GET    /entries/:entry_id/reviews/:id(.:format)         reviews#show

enter image description here

解决方法

到目前为止,临时解决方案(可能不推荐,但仍可用于编程实践)是在特定条件下隐藏和取消隐藏某些元素。

根据用户交互(例如 onClick),在更新类似于控制器更新的值时取消隐藏和隐藏元素。只需模拟刷新并更新它们指向的表单路径/控制器操作。

这对于布尔复选框形式来说通常会更好,likes or dislikes 其中变量最多只能在两个实例之间交替。因此,您不必编写太多 javascript 来处理伪输出。

不过,我相信还有更好的方法,例如 WebSocketsAction Cable。这可能有点矫枉过正,但最接近实时更新。 respond_to 似乎不起作用