2

你知道,當你從Rails的升級2到3替換這樣的:非侵入式JavaScript來更新一個元素

link_to_remote "more", :url => {...} 

與此:

link_to "more", {...}, :remote => true 

但是,你如何處理:更新選項link_to_remote?在Railscast #205瑞安貝茨演示link_to:remote和服務器響應,其中包括JavaScript代碼來更新頁面中的特定元素,但這種做法似乎對我來說是錯誤的。我希望我的服務器響應是一個簡單的HTML片段,它很容易測試,並且可以以不同的方式用於不同的頁面(客戶端)。我不認爲服務器應該知道請求頁面上目標元素的ID,因爲它將動作綁定到頁面(小型客戶端),因此使其不那麼一般(它也感覺比純HTML響應)。

因此,要明確,是有沒有辦法做這樣的事情:

link_to_remote "more", :url => {...}, :update => "products-list" 

使用Rails 3和UJS?或者,我必須編寫JavaScript來捕獲服務器的HTML響應並將其插入到頁面的正確元素中?

如果是後者,請描述最好的方法(可以使用link_to:remote的選項?)。

回答

2

我不是100%確定這是Rails認可的方式來做到這一點,但我找到了一個解決方案,工作,似乎很乾淨。假設我們有一個頁面,列出了我們數據庫中十種最受歡迎​​的產品。在到底是加載所有剩餘產品的鏈接通過AJAX:

<ul id="products-list"> 
    <li>...</li> 
    <li>...</li> 
    <li>...</li> 
    ... 
</ul> 
<%= link_to "more...", "/products/all", :id => "load-more", :remote => true %> 

服務器返回純HTML(這樣的鏈接可以在許多不同的頁面上使用和未綁定到特定的DOM的ID)。我們使用了Rails UJS司機(在這裏我使用jQuery)抓住服務器的響應,並將其插入正確的元素在頁面上引發了ajax:x事件:

<%= javascript_tag do %> 
    $("#load-more").bind("ajax:complete", function(et, e){ 
    $("#products-list").html(e.responseText); 
    }); 
<% end %> 

如果需要,我們還可以使用ajax:loading事件顯示 「微調」:

<%= javascript_tag do %> 
    $("load-more").bind("ajax:loading", function(et, e){ 
    $(this).hide(); 
    $("#products-spinner").show(); 
    }); 
<% end %> 

Rails的UJS驅動觸發其他四場賽事,以及:ajax:successajax:failureajax:beforeajax:after。查看您的應用中包含的驅動程序(public/javascripts/rails.js)以獲取更多信息。

1
在js視圖

/apps/views/product/index.js.erb可以編寫JS代碼如下面

原型:

$("products-list").update("<%= escape_javascript(render(@products))%>"); 

的jquery:

$("products-list").html("<%= escape_javascript(render(@products))%>"); 

$("products-list").append("<%= escape_javascript(render(@products))%>"); 

當請求成功時會執行

+0

這正是我說我不想做的事情,因爲它將服務器的響應與頁面上的元素(「產品列表」)聯繫起來。這可以防止我使用相同的URL更新另一個頁面,我可能想將相同的內容插入到具有不同ID的元素中。 – 2010-06-30 14:08:08

+0

因此,將要更新的元素的ID傳遞給控制器​​,並在視圖中使用它 – ErsatzRyan 2010-07-14 18:37:59

0

是的,您可以使用link_to:remote來應用後一種方法(編寫自定義JS以獲得服務器響應)。

你也可以選擇獲得json響應,然後使用JS更新頁面上的數據。在任何情況下,請記住只渲染部分,而不是整個頁面。

編輯:

一個示例代碼,這一下用ID的東西時,應使AJAX調用「更多」,然後更新頁面中的#產品列表元素:

$("#more").click(function() { 
// make a POST call and replace the content 
    $.post(, function(data) { 
     $("#products-list").html(data); 
    }); 
    }); 

你不」 t需要更多的代碼,並且你可以編寫一些助手來生成這個JS,而不是在視圖中編寫代碼。順便說一句,這是尚未UJS

+0

您可以提供一些示例代碼嗎?如果我使用':remote => true'選項,如何捕獲服務器的HTML響應並將其插入到頁面中? – 2010-07-05 23:10:37

+0

已更新我的回覆 – 2010-07-06 08:21:35

+0

感謝您的代碼,但看起來像我會使用而不是':remote => true',或者我錯過了什麼? ':remote => true'不處理POST/GET請求嗎?我需要的是一種攔截來自啓動請求的代碼之外的服務器響應的方法(在Rails UJS Prototype或jQuery「driver」中)。這有意義嗎? – 2010-07-09 23:23:06