2012-04-01 51 views
9

后,我已经有了一个形式与远程=>真。 而现在我的控制器看起来像:重定向到成功的Ajax形式

# 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的。啧!

我不知道最好的解决办法是什么。任何建议将超级真棒,在此先感谢!

-PS-我知道这已被问过一些之前,但无济于事:How to redirect after a successful AJAX form submission。似乎有许多问题相似的浮动,但没有真正的解决方案。

+0

也许我错过了一些东西,但不是它提交的AJAX表单的全部观点,它*不*需要页面加载?如果你打算重定向,那么你是否可以做一个老式的提交? – jimw 2012-04-11 23:52:08

+0

ajax用于检查验证和重复记录。然后用错误信息更新。 当表单成功时,我想要重定向到edit_path。其中有图像上传和其他事情正在进行。 – Galaxy 2012-04-12 06:46:44

+0

没错,但是你可以在没有AJAX提交的情况下做JS表单验证。我知道通过AJAX提交的唯一原因是为了避免页面加载。 – jimw 2012-04-12 09:03:07

回答

5

我想这可能是不可能的。 XMLHttpRequest处理对Ajax请求的响应。如果返回3xx响应,则XMLHttpRequest将遵循重定向本身,如果URL具有相同的来源。无论您如何设置标题,浏览器都不会意识到这一点。所以唯一的方法可能是用一些Javascript来改变window.location。

+0

设置标题是我原来想要做的。似乎不能完成! – Galaxy 2012-04-08 22:47:07

+2

设置标题不是Rails方式;因此,我不会推荐走这条路。 – 2012-04-12 14:04:44

+0

这么晚了,我正在使用'make_resourceful',但无法在'create'之后将用户重定向到正确的位置,因为它没有进入'response_for(:create)do | format |'熄灭。 任何示例控制器代码? @AaronGray – LearningROR 2016-08-30 23:02:09

3

我用的Rails responders组合来产生我的响应消息和一些conten t在我的<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 

快闪消息的内容是由Rails responders自动生成,并与now范围从闪光灯散列删除所显示的,确保如果使用者重新载入(后闪光灯已显示),它们不会再出现。

我不认为你应该制作一个指向宁静的create行动的表单,因为你总是期待重要的重定向,所以在我的情况下,我只需要重定向,如果url slug已经改变。

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

此致敬礼。

3

根据您的情况,这里的我会怎样的JavaScript注入到页面从控制器动作。你已经完成了你的行动插入像这样的逻辑部分后:

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

这应该允许你插入你window.location的或者创建一个JavaScript闪光法,并调用它,当你创建方法正确执行。

如果你正在寻找干涸控制器的动作,我会建议寻找到this Railscast about make_resourceful。 Make_resourceful自动执行每个操作的每个核心活动。它还允许您使用他们创建的挂钩,例如before :createafter :create,response_for :createafter :create_fails。通过使用这个gem,你可以根据你的方法的成功或失败来运行代码,并对它们进行更细粒度的控制。

除了这个,你应该能够初始化视图文件create.js.erb和create_fails.js.erb,包括format.js没有任何东西传递给它在你的控制器,和Rails会自动地根据控制器操作是否成功执行,运行包含javascript的文件。