Перенаправление на после успешной формы AJAX - PullRequest
10 голосов
/ 01 апреля 2012

У меня есть форма с удаленным => 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 - Я знаю, что раньше об этом спрашивали, но безрезультатно: Как перенаправить после успешной отправки формы AJAX . Похоже, что многие вопросы похожи, но реальных решений нет.

Ответы [ 3 ]

5 голосов
/ 05 апреля 2012

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

4 голосов
/ 05 апреля 2012

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

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

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

С уважением.

3 голосов
/ 06 апреля 2012

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...