2011-07-21 98 views
3

RoR中是否有功能在RoR網站中創建動態面板?我想要在主頁面上完成的任務是能夠通過單擊導航按鈕來更新面板,而不是加載全新的頁面。在Ruby on Rails上點擊按鈕時只更新div面板

位於頁面查看

在這裏,我想在我的dynamicLoadingPanel通過單擊按鈕在navButton跨度加載新的內容我home.html.erb

<span id="navButton" class="button">Content2</span> 
<div id="dynamicLoadingPanel"></div> 

我要顯示在頁面dynamicLoadingPanel是位於Pages View文件夾下的_categoryOne.html.erb文件。

感謝您的幫助!

回答

2

像其他答案一樣,你會想使用ajax。 Rails現在通過jquery_ujs.js文件和gem與jquery進行了一些很好的Ajax集成。您應該首先安裝這個gem並運行自述文件中提到的生成器:https://github.com/rails/jquery-ujs

有4-5個步驟可以採用:在您的視圖中,添加遠程鏈接以及div以接收返回的內容。創建一個與您的控制器操作命名相同的.js.erb文件,.js.erb文件呈現給您的視圖的部分以及處理遠程調用的控制器操作。您可能需要添加一條匹配控制器#動作的路線到您的新動作。

然後設置你的頁面與div加載其部分內容。部分將在ajax調用期間重新加載。這假定你的控制器被命名爲排序,你的操作是album_select。

<div id="panels"> 
    <div id="dynamicLoadingPanel"> 
    <%=render :partial=>'album_select'%> 
    </div> 
    <%=link_to 'link text', :url=>'/sort/album_select/params', :remote=>'true', :id=>'navButton'%> 
</div> 

或者使用jQuery和你的鏈接onclick事件:

$("#navButton").bind('click',function(){ 
    //post to the controller/action/params 
    $.post("/sort/album_select?album=100"); 
    }); 

在你的控制器

def album_select 
     @variables_for_your_view 

     respond_to do |format| 
     format.js 
     end 
# or use the new respond_with(@variables), and make sure to declare respond_to in your controller after the class definition 
end 

在你album_select.js.erb文件

$("#dynamicLoadingPanel").html("<%=escape_javascript(render :partial=>"album_select")%>"); 

也許會發出警報('works!');在這裏以及確保一切都連接起來......我發現很難在.js.erb文件中調試jQuery。雙重檢查報價,JavaScript轉義和其他容易錯過的JavaScript錯誤。

在您的局部

<p>info I just returned with new instance variables and fanciness</p> 

有助於手頭上有一個JavaScript調試器,和/或tail -f您的日誌文件。

2

爲此,您需要使用Ajax來做到這一點。如果你正在使用jQuery,那麼你可以做這樣的事情:

$("#navButton").click(function(){ 
    $.ajax({ 
    url : "/dynamic_panel.html", 
    success: function(data) { 
     $("#dynamicLoadingPanel").html(data); 
    } 
}); 
在軌

然後,你必須創建一個動作是響應dynamicPanel.html和呈現的內容,你可以渲染的內容爲部分。

def dynamic_panel 
    render :partial => "dynamic_panel" 
end 

記得要爲dynamic_panel請求添加路由。渲染:partial將確保它不會使用佈局。或者,您可以執行render:layout => false,因此它只會呈現視圖中dynamic_panel.html中的內容。

+0

可能爲涉及的其他頁面添加一些代碼?通常語法和函數調用是我需要看到的。謝謝 – EverTheLearner

+0

只是更新了一點答案 – Shanison

+0

這是行不通的。對於URL我使用RoR路由路徑嗎? jQuery中有一個錯誤,因爲它停在那裏。 – EverTheLearner

0

希望這個答案能幫助你推出自己的解決方案。

正如Shanison所說,這是一個你正在做的ajax調用。這個答案可以讓你在相同的路由上呈現普通的非Ajax頁面;這通常是一個好主意 - 例如,如果有人將url複製到瀏覽器中,他們會期望整頁而不是局部頁面。我也將在這裏使用jQuery。

首先確保的是,當該路徑與非HTML格式訪問正確的部分呈現(我用的.js這裏):

類別/ show.js.erb(只渲染的相關部分):

<%= render 'categoryOne' %> 

類別/ show.html.erb(具有完整的頁面):

<!-- other page stuff --> 
<div id="dynamicLoadingPanel"> 
<%= render 'categoryOne' %> 
</div> 
<!-- the rest of the page --> 

你的頁面:

<%= link_to 'Content2', category_path(category), 
      :class => 'ajax_link', :rel => 'dynamicLoadingPanel' %> 
<div id="dynamicLoadingPanel"></div> 

的application.js:

$('a.ajax_link').click(function(e){ 
    // check that this element exists first 
    if($('#' + $(this).attr('rel'))) { 
     // stop the link from loading normally 
     e.preventDefault(); 

     // load the .js version of the page into the div 
     $('#' + $(this).attr('rel')).load(this.href + '.js'); 
    } 
}); 

什麼的JavaScript所做的是讓所有a的與類ajax_link打開其href在其ida DOM節點的rel

使用此代碼,您可以在具有.js視圖的任何路徑上的任何id'd節點中進行任何鏈接加載。如果用戶的javascript被關閉/崩潰或從外部鏈接點擊,他們會得到正常的頁面。

4

一定要結帳pjaxDemo)。 @dhh在RailsConf '11的主題演講中提到了這一點,它真的讓你大開眼界!謝天謝地,他還爲Rails 3.1+編寫了一個gem,它將pjax集成到資產管道中。

我使用Rails 3.0應用程序測試過它,它確實很有趣。您的應用感覺速度更快,反應更快希望它將作爲Rails未來版本的默認集成。 不幸的是,我當前的Rails項目仍然是Rails 3.0,但我會盡快實現pjax。

+0

感謝pjax的介紹,解答了這個問題,以便我可以稍後再回到這個答案:) – rubish

0
# app/controllers/my_controller.rb 
class MyController < ApplicationController 
    def index 
    end 

    def my_action 
    end 
end 

# routes.rb 
map '/my_action', 'my#my_action', as: 'my_action'# via: :get 

# app/views/layouts/application.html.erb 
<%= yield %> 

# app/views/my/index.html.erb 
<span id="navButton" class="button"><%= link_to "Content2", my_action_path, remote: true %></span> 
<div id="dynamicLoadingPanel"></div> 

# app/views/my/my_action.js.erb 
$('#dynamicLoadingPanel').html('<%= escape_javascript(render(template: "my/my_action.html")) %>'); 

# app/views/my/my_action.html.erb 
<p>My content here</p> 
相關問題