使用AJAX但仍允许在Rails中使用$(document).ready

时间:2013-01-05 00:23:07

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

我有以下文件:

layouts/application.html.erb

<div class="container">
  <br>
  <%= flash_messages %>
  <%= yield %>
  <script type="text/javascript">
    $(document).ready(function() {
      $('select').each(function(idx, elem) {
        var $elem = $(elem);
        $elem.select2();
      });

      <%= yield :document_ready %>
    });
  </script>
</div>

这是index.html.erb:

user_transactions/index.html.erb

<% content_for :document_ready do %>
<% render :partial => 'shared/datepicker' %>
<% end %>
<h3><%= I18n.translate("user_transaction.add") %></h3>
...

现在我想拥有一个更流畅的界面,所以我在控制器中做到了这一点:

user_transactions_controller.erb
def index
  @company = Company.find(params[:company_id])
  @user_transactions = @company.user_transactions.order("date DESC").all

  respond_to do |format|
    format.js { render :layout => false }
    format.html # index.html.erb
    format.json { render json: @user_transactions }
  end
end 

并创建了以下文件:

user_transactions/index.js.erb    
document.getElementById('dashboard-body').innerHTML = 
  '<%= escape_javascript(render(:file => "user_transactions/index.html.erb")) %>'

我用以下内容调用该页面:remote =&gt;真正的选择。我不知道它是否好,但它有效,我在这里找到了这种技术:How to return a the index.html.erb in the js.html.erb file

然而,我遇到的一个问题是没有任何javascript代码可以正常工作。需要运行select2(在布局中),还有视图index.html.erb本身(datepicker)中声明的部分。

如何保留javascript但保留ajax和快速界面?

2 个答案:

答案 0 :(得分:2)

找到了解决方案。

JavaScript存在于文档中,因为我是从使用应用程序布局的页面调用它。但是,它不会调用document.ready甚至更多,一旦调用document.ready(第一次),事件就会解除绑定。

为了保持解决方案DRY,我解决了这个问题:

我为document.ready要执行的部分创建了我需要的每个javascript函数的partials。我更改了layouts / application.html.erb文件以使用那些部分(或者至少是我想要在每个表单上的部分)和user_transactions / index.js.erb中我调用了我需要的部分。

所以我在index.js.erb

中添加了这个部分
$(document).ready(function() {
  <%= render(:partial => "shared/select2") %>
  <%= render(:partial => "shared/datepicker") %>
});

答案 1 :(得分:1)

我有两个错误的猜测和几个问题:

当您使用以下网址调用该页面时:remote =&gt;是的,您确认您的JS出现在页面上吗?而且,你究竟在哪里调用这个页面?

我怀疑您的脚本可能不在页面上,因为您指定了错误的布局,因此除非您从使用应用程序布局的页面调用它,否则application.html.erb文件中的任何内容都不可用。

我也认为正在发生的事情的一部分是当你渲染innerHTML时,你拉入了所有代码,但JS实际上并没有再次执行,所以document.ready中的脚本不是了解您添加到页面的新内容。设置innerHTML后,您必须再次调用JS。

您可以将.each打包到一个函数中并在document.ready上调用一次,然后在填充innerHTML之后再次调用它。

这是一个类似的问题,有更好的解释:Rails Ajax: .js.erb rendered as text, not JS

我希望我走在正确的轨道上。