在Ruby on Rails上单击按钮时仅更新div面板

时间:2011-07-21 05:24:52

标签: ruby-on-rails ruby-on-rails-3

RoR中是否有功能在RoR网站中创建动态面板?我想在主页面中完成的是能够通过单击导航按钮更新面板,而不是加载一个全新的页面。

位于“页面视图”

在这里,我想在我的dynamicLoadingPanel中加载新内容,点按navButtonhome.html.erb范围内的按钮:

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

我想在dynamicLoadingPanel中显示的页面是位于“页面视图”文件夹下的_categoryOne.html.erb文件。

感谢您的帮助!

5 个答案:

答案 0 :(得分:4)

请务必结帐pjaxDemo)。 @dhh在RailsConf '11的主题演讲中提到过这一点,它真的让你大吃一惊!值得庆幸的是,他还为Rails 3.1+写了一个gem,它将pjax集成到资产管道中。

我使用Rails 3.0应用程序进行了测试,它真的很震撼。您的应用感觉更快,响应更快。希望它将在未来的Rails版本中默认集成。 不幸的是我目前的Rails项目仍然是Rails 3.0,但我会在其中实现pjax。

答案 1 :(得分:2)

为此,您需要使用Ajax来执行此操作。如果您使用的是jQuery,那么您可以这样做:

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

然后在rails中,您必须创建一个响应dynamicPanel.html并呈现内容的操作,您可以将该内容呈现为部分内容。

def dynamic_panel 
  render :partial => "dynamic_panel"
end

记得为dynamic_panel请求添加路由。渲染:部分将确保它不会使用布局。或者,您可以执行render:layout =&gt; false,因此它只会在视图中的dynamic_panel.html中呈现内容。

答案 2 :(得分: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调用期间重新加载。这假定您的控制器名为sort,您的操作是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")%>");

可能会发出警报('有效!');在这里,以确保一切都链接...我发现很难调试.js.erb文件中的jquery。双重检查引号,javascript转义,以及其他容易错过的javascript错误。

在你的部分

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

帮助您手头有一个javascript调试器,和/或tail -f您的日志文件。

答案 3 :(得分:0)

希望这个答案可以帮助您推出自己的解决方案。

正如Shanison所说,这是你正在制作的ajax电话。这个答案让你在相同的路线上渲染普通的非ajax页面;这通常是一个好主意 - 例如,如果有人将网址复制到浏览器中,他们会期望整页而不是部分网页

我也会在这里使用jQuery。

首先确保在使用html以外的格式访问路径时呈现正确的partial(我在这里使用.js):

categories / show.js.erb(仅渲染相关部分):

<%= render 'categoryOne' %>

categories / 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的{​​{1}}课在ajax_linkhref的DOM节点中打开id } a

使用此代码,您可以在任何具有.js视图的路径上的任何id'd节点中加载任何链接。如果用户的javascript被关闭/崩溃或从外部链接点击,他们将获得正常页面。

答案 4 :(得分: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>