1

私はちょうどRailsを学んでいるので、助けていただければ幸いです。:remote => trueon についておそらく 10 個のチュートリアルを見てきましたがform_for、それらはすべて互いにコピーしているように見えます (同様に紛らわしいです)。

このチュートリアルはその 1 つです。

私の Web アプリはほぼすべて 1 つのページにあり、「送信フォーム」はポップアップ ライトボックス内にあります。これは、form_for コードが実際には index.html.erb 内にあることを意味します。また、新しい @playlist インスタンス変数が作成されることも意味しますindex(これを in にする代わりにnew)

私の最終目標はこれです:

if @playlist.saveを返します。WITH a :noticetrueにユーザーをリダイレクトしたいと思います。root_path成功メッセージなどでフォームを更新する必要はありません。保存成功時にハードリダイレクトが必要です。

if @playlist.saveページを更新せずにエラーをライトボックス フォームに追加するcreate.js.erbfalse内のコードをレンダリングします。多くのチュートリアルでは、フォーム全体を html として再レンダリングしてから、コンテンツをその場で置き換えたいと考えているようです。私は(できれば)エラーをフォームに送信して挿入したいのですが、フォーム全体を再レンダリングして置き換えるのは、必要以上に複雑に思えると思います。

今のところ、私のコードは混乱しています。特に:

  • respond_toブロック。これは、実際にここで何が起こるかについての最大の混乱点です。私は多くの異なるコードを試しましたが、何も機能しません
  • create.js.erb が正しいかどうかわかりません
  • 私は create.html.erb を持っていません - リダイレクトしたいだけなので、これは正しいと思います

私のフォームの最初の行

<%= form_for @playlist, :remote => true do |f| %>

私の全体の PlaylistsController

class PlaylistsController < ApplicationController

  before_filter :load_genres, :only =>[:index, :user]
  before_filter :new_playlist, :only => [:index, :new, :create]

  def index
    @playlists = Playlist.order('created_at DESC').page(params[:page]).per(30)
  end

  def new
  end

  def create
    respond_to do |format|
      if @playlist.save
        # ???
        format.html { redirect_to root_path, :notice => "Playlist submitted" }
      else
        # ???
        format.js { render :js => @playlist.errors, :status => :unprocessable_entity }
      end
    end
  end

  def user
    @playlists = Playlist.order('created_at DESC').where(:username => params[:username]).page(params[:page]).per(30)
  end

  def listen
    playlist = Playlist.find(params[:playlist_id])
    playlist.update_attribute(:listens, playlist.listens + 1)
    render :nothing => true
  end

  private

  def load_genres
    @genres = Genre.order(:name)
  end

  def new_playlist
    @playlist = Playlist.new(:title => params[:title], :url => params[:url], :description => params[:description])
  end

end

create.js.erb

jQuery(function($) {
    alert('createjs called');
    $('#submit-form form').on('ajax:error', function(event, xhr, status, error){

        var responseObject = $.parseJSON(xhr.responseText), 
            errors = $('<ul />');

        $.each(responseObject, function(index, value){
            errors.append('<li>' + value + '</li>');
        })

        $(this).find('.submit-playlist-errors').html(errors);
    });
});
4

1 に答える 1

3

flash私が正しく理解している場合は、フォームがあり、フォームが保存されている場合に通知してリダイレクトしたいと考えています。フォームが無効な場合は、エラーを表示します。

フォーム (または任意のリクエスト) をさまざまな形式 (通常は html、json、js) で Rails アプリに送信できます。これは、提供する URL で指定されます。

playlist_path(@playlist)
# => /playlists/1

playlist_path(@playlist, :format => "json")
# => /playlists/1.json

playlist_path(@playlist, :format => "html")
# => /playlists/1.html
# ... etc

respond_toフォーマットは、ブロックで指定されたどの種類の応答を使用するかを Rails に伝えます。

これが明確な場合は、使用する形式を決定する必要があります。

formatを指定するjsと、応答は実行済みとして扱われscriptます。フォームが有効な場合は、ユーザーに JavaScript を送信して、目的のページにリダイレクトすることができます。フォームが無効な場合は、エラー メッセージを表示できるように HTML を変更できます。クライアント側のコードは必要ありません。

respond_to do |format|
  if valid
    format.js { render "valid" }
  else
    format.js { render "invalid", :status => :unprocessable_entity }
  end
end

# valid.js.erb
window.location = <%= your_path %>

# invalid.js.erb
// whatever to display errors

使用するjsonと、フォームが無効な場合にユーザーまたはエラーをリダイレクトするためにリダイレクト URL を返すことができます。このソリューションを処理するには、クライアント側で Javascript が必要であることに注意してください。

# controller
respond_to do |format|
  if valid
    format.json { render :json => your_path }
  else
    format.json { render :json => @object.errors, :status => :unprocessable_entity }
  end
end

# client side javascript
$("form")
  .on("ajax:success", function(event, data, status, response) {
    window.location = data
  })
  .on("ajax:error", function(event, response, error) {
    // logic to handle errors
  })

formatを使用することもできhtmlます (format を に設定するhtmlか、format をまったく指定しないことにより)。ただし、使用する場合は、 (クライアント側の JavaScript を使用する):remote => trueと同じ方法で処理する必要があります。応答としてjson使用すると、ユーザーではなく要求がリダイレクトされます。redirect_to

ユーザーがリダイレクトされた後にフラッシュメッセージを表示するかどうかはわかりませんが、次の方法で試すことができます:

respond_to do |format|
  if valid
    format.html { 
      flash[:notice] = "Playlist submitted"
      render :json => your_path }
  else
    format.html { render :json => @object.errors, :status => :unprocessable_entity }
  end
end

# client side javascript
//...

respond_toうまくいけば、これでブロックが乾きます。

于 2012-09-24T17:16:03.787 に答える