2012-09-24 40 views
1

我只是在學習Rails,並希望得到任何幫助。我已經在form_for上查看了:remote => true的10個教程,它們似乎都是相互複製的(同樣令人困惑)。:remote =>真正的混淆與form_for

本教程是其中之一:http://tech.thereq.com/post/18910961502/rails-3-using-form-remote-true-with-jquery-ujs

我的web應用程序是幾乎所有在一個頁面上,和我的「提交表單」是一個彈出式燈箱內。這意味着form_for代碼實際上在我的index.html.erb中。這也意味着index創建一個新的@playlist實例變量(而不是有這是new

我的最終目標是這樣的

if @playlist.save回報true,我想將用戶重定向到root_path WITH a:notice。沒有必要用成功消息或類似的東西來更新表單。我想要保存成功的硬重定向。

if @playlist.save返回false,我想渲染create.js.erb中的代碼,它會將錯誤追加到lightbox窗體中而不刷新頁面。 note很多教程似乎都希望將整個表單重新渲染爲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); 
    }); 
}); 
+0

我其實是有點困惑你使用,你需要達到什麼樣的掙扎什麼。什麼工作,什麼不是。你能簡化和打破你的問題嗎? – simonmorley

+0

相信我我曾試圖在其他論壇和其他論壇上將其分解。這很難解釋,我試圖讓它真正清楚我在找什麼。截至目前,它只是沒有工作,時期。我知道這個問題是我的respond_to塊,這主要是因爲我不明白它和所有我讀過的教程混淆了這個話題 – Tallboy

+0

我已經意識到一個錯誤是,我有這樣的:'@playlist = Playlist.new( :title => params [:title],:url => params [:url],:description => params [:description])'。它應該是'params [:播放列表]'。我會在一瞬間給出確切的錯誤 – Tallboy

回答

2

如果我理解正確的話,你有一個表單,你想用flash通知重定向如果表單保存。如果表單無效,您希望顯示錯誤。

您可以將表單(或任何請求)以不同格式(通常爲html,json和js)發送到rails應用程序。這在您提供的網址中指定。

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

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

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

該格式告訴導軌在您的respond_to塊中指定使用哪種響應。現在

如果這是明確的,你必須決定使用哪種格式。

如果指定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 
    }) 

您還可以使用html格式(通過設置格式html或不指定格式在所有)。但是,如果你使用:remote => true你也會有同樣的方式來對待它作爲json(有客戶端的JavaScript)。如果您使用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塊。

+0

太棒了,謝謝。讓我看看 – Tallboy

+0

有沒有一種方法可以在不使用javascript的情況下重定向?就像服務器發回的響應重定向它們一樣? – Tallboy

+1

恐怕沒有這種方式。您可以通過調用'render:js =>「window.location =#{your_path}」''''''''''''''''''''''''' – DaveTsunami