如何使用变量控制表单提交远程?

时间:2013-07-02 08:20:29

标签: ruby-on-rails ruby-on-rails-3

我想控制何时刷新页面(respond_to format.html)以及何时切换按钮(respond_to format.js),方法是将本地变量传递给部分用于remote:true(remote:remote_flag),但该变量为remote_flag总是假的。

-------------父部分----------------

<% if current_user.following?(user_event) %>
  <%= render partial: 'shared/remove_favorite', 
    locals: { user_event: user_event, remote_flag: true } %>
<% else %>
  <%= render partial: 'shared/add_favorite', 
    locals: { user_event: user_event, remote_flag: true } %>
<% end %>

-------------添加最喜欢的部分----------------

<%= form_for(current_user.favorites.build(followed_event_id: user_event.id), 
  html: { id: "event_number_#{user_event.id}" }, remote: remote_flag) do |f| %>
  <div class="hidden"><%= f.hidden_field :followed_event_id %></div>
  <%= f.submit "Add to favorites %>
<% end %>

-------------删除最喜欢的部分----------------

<%= form_for(current_user.favorites.find_by_followed_event_id(user_event),
  html: { id: "event_number_#{user_event.id}", method: :delete }, remote: remote_flag) do |f| %>
  <%= f.submit "Remove from favorites %>
<% end %>

2 个答案:

答案 0 :(得分:2)

@remote_flag是一个实例变量,而不是局部变量,因此它不会传递给具有locals: { user_event: user_event, remote_flag: false }构造的部分变量。由于未设置,因此它(默认情况下)为nil,并且在条件语句中的行为类似于false。相反,您应该使用传递的局部变量remote_flag

<%= form_for(current_user.favorites.find_by_followed_event_id(user_event),
  html: { id: "event_number_#{user_event.id}", method: :delete }, remote: remote_flag) do |f| %>
  <%= f.submit "Remove from favorites %>
<% end %>

并通过locals: {...}构造传递变量或在控制器中显式设置实例变量:

@remote_flag = !!condition

答案 1 :(得分:1)

哇,我终于解决了这个问题。哇,很多调查,但我一路上学到了很多东西。我会在这里分享我的解决方案。

所以我的情况是我正在尝试干,所以我有两个部分用于“添加到收藏夹”和“从收藏夹中删除”按钮。在我的事件管理应用程序中,搜索结果页面显示事件,最初呈现“添加到收藏夹”按钮部分。当用户单击按钮时,AJAX表单提交将使用“从收藏夹中删除”部分替换该部分。这样,如果用户改变主意,用户可以在添加到收藏夹之间进行切换。

但我也想在用户个人资料页面和收藏夹索引页面上使用那些“添加到收藏夹”/“从收藏夹中移除”部分,在这些页面上,当用户点击“从收藏夹中删除”时,我不知道我想要显示“添加到收藏夹”按钮,我想刷新页面,以便收藏列表减去删除的项目。在这种情况下,我根本就不进行AJAX调用。

为了实现这一点,我需要一种方法来控制远程:对于表单,对于AJAX调用是true,对于HTML(页面刷新)调用是false。以下代码(仅显示相关内容)是我如何做到的。

希望这有助于其他人。

----------------- parent partial -----------------

这里在父部分中,设置remote_flag:true可以防止通过AJAX调用进行页面刷新,而remote_flag:false则是HTML调用,用于页面刷新。

<% if current_user.following?(user_event) %>
  <%= render partial: 'shared/remove_favorite', 
    locals: { user_event: user_event, remote_flag: true } %>
<% else %>
  <%= render partial: 'shared/add_favorite', 
    locals: { user_event: user_event, remote_flag: true } %>
<% end %>

-------------添加最喜欢的部分----------------

hidden_​​field:remote_flag允许控制器通过params [:remote_flag]进行访问。

<%= form_for(current_user.favorites.build(followed_event_id: user_event.id), 
  html: { id: "event_number_#{user_event.id}" }, remote: remote_flag) do |f| %>
  <div class="hidden"><%= f.hidden_field :followed_event_id %></div>
  <%= hidden_field_tag :remote_flag, value: remote_flag %>

  <%= f.submit "Add to favorites", 
    class: "info_button_small user_event_summary_item" %>
<% end %>

-------------删除最喜欢的部分----------------

hidden_​​field:remote_flag允许控制器通过params [:remote_flag]进行访问。

<%= form_for(current_user.favorites.find_by_followed_event_id(user_event),
  html: { id: "event_number_#{user_event.id}", method: :delete }, remote: remote_flag) do |f| %>
  <%= hidden_field_tag :remote_flag, value: remote_flag %>

  <%= f.submit "Remove from favorites", class: "info_inline_control info_button_small user_event_summary_item" %>
<% end %>

----------------收藏控制器----------------

在控制器中,此代码允许create.js.erb和destroy.js.erb访问@remote_flag:

@remote_flag = params[:remote_flag]


class FavoritesController < ApplicationController
  before_filter :signed_in_user

  def create
    @remote_flag = params[:remote_flag]
    @user_event = UserEvent.find(params[:favorite][:followed_event_id])
    current_user.follow!(@user_event)
    respond_to do |format|
      format.html { redirect_to user_path(current_user) }
      format.js
    end
  end

  def show
    @user = current_user
  end

  def destroy
    @remote_flag = true
    @user_event = Favorite.find(params[:id]).followed_event
    current_user.unfollow!(@user_event)
    respond_to do |format|
      format.html { redirect_to user_path(current_user) }
      format.js
    end
  end
end

--------------- create.js.erb -------------------

<% if @current_user.following?(@user_event) %>
  $("#event_number_<%= @user_event.id %>").replaceWith('<%= escape_javascript(render(
    partial: 'shared/remove_favorite', locals: { user_event: @user_event, remote_flag: @remote_flag })) %>');
<% end %>

--------------- destroy.js.erb -------------------

<% if !@current_user.following?(@user_event) %>
  $("#event_number_<%= @user_event.id %>").replaceWith('<%= escape_javascript(render(
    partial: 'shared/add_favorite', locals: { user_event: @user_event, remote_flag: @remote_flag })) %>');
<% end %>