2012-04-01 1 views
9

У меня есть форма с remote => true. И сейчас мой контроллер выглядит следующим образом:Перенаправление после успешной формы 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. Sheesh!

Я не уверен, что лучшее решение Любые советы были бы супер-потрясающими, спасибо заранее!

- PS - Я знаю, что это было задано несколько раньше, но безрезультатно: How to redirect after a successful AJAX form submission. Кажется, есть много вопросов, похожих на плавающие, но реальных решений нет.

+0

Возможно, у меня что-то не хватает, но не все ли форма представления AJAX, что он * не требует загрузки страницы? Если вы собираетесь перенаправить, можете ли вы не просто сделать старомодный подарок? – jimw

+0

Ajax используется для проверки валидации и дублирования записей. Затем обновите сообщение с сообщением об ошибке. Когда форма будет успешной, я тогда хочу перенаправить на edit_path. У чего есть загрузка изображений и другие вещи. – Galaxy

+0

Правильно, но вы можете выполнить проверку формы JS без представления AJAX. Единственная причина, по которой я знаю, отправлять через AJAX, - это избежать загрузки страницы. – jimw

ответ

5

Я думаю, что это невозможно. Ответ на запрос Ajax обрабатывается XMLHttpRequest. Если возвращается ответ 3xx, XMLHttpRequest будет следовать самому перенаправлению, если URL-адрес имеет тот же источник. Независимо от того, как вы устанавливаете заголовки, браузер не может этого знать. Таким образом, единственным способом может быть изменение window.location с некоторым Javascript.

+0

Настройка заголовков была тем, чем я был оригинален, хотел быть в состоянии сделать. Похоже, это невозможно! – Galaxy

+2

Настройка заголовков не является способом Rails; поэтому я бы не рекомендовал идти по этому маршруту. –

+0

Так поздно, я в настоящее время использую 'make_resourceful', но не могу перенаправить пользователя в нужное место после' create', он переходит в 'show' всегда, поскольку он не входит в' response_for (: create) do | format | 'и выходит. любой код контрольного образца? @AaronGray – LearningROR

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 области, которая удаляет из флэш-хэш, гарантируя, что если перезагружается пользователем (после того, как вспышка была отображена), они не появятся снова.

Я не верю, что вы должны когда-либо сделать форму, указывающую на спокойное действие на удаленном, потому что вы всегда ожидаете критической переадресации, поэтому в моем случае мне нужно только перенаправить, если изменился URL-адрес.

Я надеюсь, что это поможет. Это не решение, а просто то, как я справлялся с некоторыми из тех же проблем.

С уважением.

3

В соответствии со своим сценарием, вот как я буду вводить javascript на страницу из действия контроллера. После того, как вы завершили логическую часть вашей вставки действия что-то вроде этого:

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

Это позволит вам вставить вы window.location или создать яваскрипт метод вспышки и вызвать его, когда ваш метод создания правильно выполняет.

Если вы ищете DRY для своих действий с контроллером, я бы порекомендовал посмотреть на this Railscast about make_resourceful. Make_resourceful автоматически выполняет каждое основное действие для каждого действия.Он также позволяет вам использовать крючки, которые они создали, такие как before :create, after :create, response_for :create и after :create_fails. Используя этот драгоценный камень, вы можете запускать код, основанный на успехе или неудаче ваших методов, и иметь более тонкий контроль над ними.

В дополнение к этому вы должны иметь возможность инициализировать create.js.erb и create_fails.js.erb в вашем файле вида, включить format.js без каких-либо переданных ему в контроллер контроллеров, а Rails будет автоматически запустите этот файл, содержащий javascript, в зависимости от успешного выполнения действия контроллера.

Смежные вопросы