2011-08-30 72 views
1

我的設置:Rails的3.0.9,紅寶石1.9.2,1.6.2的jQuery導軌3的jQuery識別 「這」 對象

HTML

<textarea id="photo-42-9" class="comment_box">Write a comment...</textarea> 

jQuery的

$('#newsfeed').delegate('.comment_box', 'keydown', function (event){ 
    if(event.keyCode == 13) { 
    event.preventDefault(); 
    $.post('/comments', { title: ..., description: ... }); 
    } 
}); 

滑軌

comments_controller.rb  
    def create 
    @comment = Comment.new 

    respond_to do |format| 
     format.html # new.html.erb 
     format.js 
    end 
    end 

create.js.erb 
$("<%= escape_javascript(render 'show_comments') %>").insertBefore(???); 

render 'show_comments' return我想在textarea之前插入一個<div>stuff</div>。我可以在#photo-42-9上使用選擇器,但該ID是動態的,具體取決於我點擊的textarea元素。如何訪問create.js.erb中的this對象?

+1

怎麼樣,如果你通過ID作爲後的參數,與冠軍一起,描述? – e3matheus

+0

猜猜我可以,但我希望很容易在'create.js.erb'中獲得'this'對象? – Bob

+0

只記得一個更方便的方法來做到這一點,我的答案更新如下。 – Andrew

回答

5

在JS:

$('#newsfeed').delegate('.comment_box', 'keydown', function (event){ 
    if(event.keyCode == 13) { 
    event.preventDefault(); 
    var params = { title: ..., description: ... }; 
    var $this = $(event.target); 
    $.post('/comments', params, function(response) { 
     $this.before(response); 
    }); 
    } 
}); 

和紅寶石(我猜,我不做紅寶石):

"<%= escape_javascript(render 'show_comments') %>" 

正如你看到的, 「這個」 不傳遞給RB。相反,$ .post函數等待rb響應,並將其粘貼到文本區域(事件目標)之前。這種方式更好,因爲你所有的js代碼實際上都在你的js代碼中。

注意:「$(response).insertBefore($this)」將工作相同。

注意:如果您將$ this assigination從「if」移出,您可以輕鬆檢查新評論是否爲空且不同於已有的評論(event.keyCode == 13 && $this.val() != '' && $this.val() != $this.prev().text())。同樣,您可以在「$this.before」插入之後用$this.val('')清空textarea。

+0

您的解決方案有效,我同意,它的方式更清潔。我想到了這是否應該成爲首選方法,即儘可能將JS代碼保留在JS中並關閉Rails。幾個問題,爲什麼我不能使用'$(this)'而不是'var $ this = $(event.target)'?另外JS沒有正確渲染Rails的轉義JS輸出,是否有JS調用來處理? – Bob

+0

你不能直接使用「$(this)」,因爲「this」指的是事件本身(keydown),而不是keydown的目標。但是,目標是*包含在事件中,可以通過「event.target」訪問。實際上,目標(你的「this」)被傳遞給「委託」函數(或者點擊,綁定,無論什麼),誰不通過回調函數(我們寫的)。關於鐵路輸出的呈現,我不能真正幫助你。你嘗試過'$ this.before(unescape(response));'? – roselan

+0

感謝您的解釋。我之前嘗試過'unescape',但沒有運氣,感謝嘗試。 – Bob

2

無法訪問this - 這是在客戶端腳本中確定 - 從您的控制器上執行服務器端的創建操作在不同的範圍和不同的編程語言。

您有兩種選擇。您可以將選擇器信息與請求一起傳遞,以便它可以由服務器確定,或者,您可以系統地命名選擇器,以便您的選擇器可以由對象本身的屬性決定。

後者更簡單。它看起來像你的形式張貼在照片的評論,所以舉例來說,如果你使用

div_for @photo 

爲您生成要評論照片的容器,那麼你可以隨時使用訪問容器:

dom_id @photo 

那麼你可以使用繼承來選擇你想要插入的textarea。

在你create.js.erb:

$(...content...).append('#<%= dom_id @photo %>') 

很明顯,你將不得不結構,以適應您正在與之交互的內容。附加到外部照片容器的內部或者選擇要插入的評論或其他類似內容可能更容易。

或者,您可以在表單中放置隱藏字段,其中包含生成的表單ID,如hidden_field_tag :form_id, form_id_goes_here

然後在你的控制器設置:

@selector = params[:form_id] 

而在你create.js.erb:

$(...content...).insertBefore('<%= escape_javascript @selector %>')