【问题标题】:Redirect to after successful ajax form成功的ajax表单后重定向
【发布时间】:2012-04-01 09:33:32
【问题描述】:

我有一个带有 remote => true 的表单。 现在我的控制器看起来像:

  # POST /items
  # POST /items.json
  def create
    @item = @store.items.build(params[:item])

    respond_to do |format|
      if @item.save
        format.html { redirect_to edit_admin_item_path(@item), :flash => {:success => "#{@item.name} was successfully created."} }
        format.js { render :js => "window.location.href = ('#{edit_admin_item_path(@item)}');"}
        format.json { render json: @item, status: :created, location: @item }
      else
        format.html { render action: "new" }
        format.js { render :partial => 'fail_create.js.erb', :locals => { :ajax_errors => @item.errors.full_messages } }
        format.json { render json: @item.errors, status: :unprocessable_entity }       
      end
    end
  end

这很有效,但感觉很笨拙。它也不允许我使用快速通知,这确实是一个悲伤的时刻。

理想情况下,我觉得我应该能够简单地使用“format.js {redirect_to...} 或检查请求标头和redirect_to。Sheesh!

我不确定最好的解决方案是什么。任何建议都会非常棒,在此先感谢!

-- PS -- 我知道之前有人问过这个问题,但无济于事:How to redirect after a successful AJAX form submission。似乎有很多类似的问题在流传,但没有真正的解决方案。

【问题讨论】:

  • 也许我遗漏了一些东西,但 AJAX 表单提交的重点不是它不需要 需要页面加载吗?如果你要重定向,你可能不做一个老式的提交吗?
  • ajax 用于检查验证和重复记录。然后使用错误消息更新。当表单成功时,我想重定向到edit_path。其中有图片上传和其他事情。
  • 对,但是您可以在不提交 AJAX 的情况下进行 JS 表单验证。我知道通过 AJAX 提交的唯一原因是避免页面加载。

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


【解决方案1】:

我认为这可能是不可能的。 Ajax 请求的响应由 XMLHttpRequest 处理。如果返回 3xx 响应,则 XMLHttpRequest 将跟随重定向本身,如果 URL 是同源的。无论您如何设置标题,浏览器都无法意识到这一点。所以唯一的办法就是用一些 Javascript 来改变 window.location。

【讨论】:

  • 设置标题是我最初想要做的。好像做不到!
  • 设置标题不是 Rails 的方式;因此,我不建议走那条路。
  • 这么晚了,我目前正在使用make_resourceful,但在create 之后无法将用户重定向到正确的位置,它总是转到show,因为它没有进入response_for(:create) do |format| 并转到出去。任何示例控制器代码? @AaronGray
  • @LearningROR 抱歉,我没有更多使用 make_resourceful 的应用程序。我会创建一个新问题,看看您是否可以通过这种方式获得帮助。 :)
  • @AaronGray。非常感谢。至少您的评论比任何人都没有回应更有意义。 :) 我目前没有回应的问题是:http://stackoverflow.com/questions/39238691/unable-to-redirect-to-index-path-after-create。如果您只有一个带有 DRY 控制器的代码库,并且仅对整个项目进行建模,那么任何小型应用程序都可以帮助我。 :) 我现在和我的客户中间。 :(
【解决方案2】:

我使用Rails responders 的组合来生成我的响应消息和我的<action>.js 文件中的一些内容。

内容——比如update.js 看起来像这样:

// Checks if the article slug has changed.
// If it has the entire page should be reloaded at that new location.
<%= reload_if_slug_changed @article, params[:id] %>

// Displays the flash notices
// See ApplicationHelper#js_flash_response
<%= js_flash_response %>

在一些帮助程序中定义了不同的方法(在我的例子中是我的 ApplicationHelper)。不同方法的内容如下:

def js_flash_response
  if flash.now[:notice].present?
    js = "$('#notice').html('#{flash.now[:notice]}').change();"
  elsif flash.now[:alert].present?
    js = "$('#alert').html('#{flash.now[:alert]}').change();"
  end
end

def reload_if_slug_changed object, expected_value
  "window.location.href = '#{url_for [:edit, object]}';" if object.slug != expected_value
end

flash 消息的内容由Rails responders 自动生成并以now 范围显示,该范围从flash 哈希中删除,确保如果用户重新加载(在显示flash 后)它们不会重新出现.

我不认为您应该将指向宁静的create 操作的表单设置为远程操作,因为您总是希望进行关键重定向,因此在我的情况下,我只需要在 url slug 已更改时进行重定向.

我希望这会有所帮助。这不是一个解决方案,而只是我处理一些相同问题的方式。

最好的问候。

【讨论】:

    【解决方案3】:

    在您的场景下,我将通过控制器操作将 javascript 注入页面。完成操作的逻辑部分后,插入如下内容:

    render :update do |page|
        page << "javascript_here"
    end
    

    这应该允许您插入 window.location 或创建一个 javascript flash 方法并在您的 create 方法正确执行时调用它。

    如果您想要干掉您的控制器操作,我建议您查看this Railscast about make_resourceful。 Make_resourceful 自动为每个动作执行每个核心活动。它还允许您利用他们创建的挂钩,例如 before :createafter :createresponse_for :createafter :create_fails。通过使用此 gem,您可以根据方法的成功或失败运行代码,并对它们进行更细粒度的控制。

    除此之外,您应该能够在视图文件中初始化 create.js.erb 和 create_fails.js.erb,在控制器中包含 format.js 而无需传递任何内容,Rails 将自动运行包含 javascript 的文件取决于控制器操作是否成功执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-19
      • 2023-03-20
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多