【问题标题】:Use AJAX but still allow $(document).ready in Rails在 Rails 中使用 AJAX 但仍然允许 $(document).ready
【发布时间】:2013-01-05 00:23:06
【问题描述】:

我有以下文件:

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 => true 选项调用该页面。我不知道它是否好,但它有效,我在这里找到了这种技术:How to return a the index.html.erb in the js.html.erb file

然而,我面临的一个问题是所有的 javascript 代码都不再工作了。有需要运行的 select2(在布局中),还有在视图 index.html.erb 本身(datepicker)中声明的部分。

如何在保留 javascript 的同时保留 ajax 和快速界面?

【问题讨论】:

  • 我想知道ERB是否不喜欢&lt;script&gt;标签在&lt;head&gt;之外?
  • 你的 JavaScript 控制台有错误吗?
  • @IanAtkin ERB 只是带有 ruby​​ 标签的文本。在这种情况下,该文本恰好被格式化为 HTML。 ERB 根本不关心 HTML 的结构。事实上,它很高兴让你完全搞砸了。

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


【解决方案1】:

找到了解决办法。

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

为了保持溶液干燥,我这样解决了:

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

所以我在 index.js.erb 中添加了这部分

$(document).ready(function() {
  <%= render(:partial => "shared/select2") %>
  <%= render(:partial => "shared/datepicker") %>
});

【讨论】:

    【解决方案2】:

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

    当您使用 :remote => true 调用页面时,您是否验证了您的 JS 存在于页面上?而且,您究竟是从哪里调用该页面的?

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

    我还认为发生的部分情况是,当您渲染 innerHTML 时,您提取了所有代码,但 JS 实际上并没有再次执行,因此 document.ready 中的脚本不知道新的您添加到页面的内容。设置innerHTML后需要再次调用JS。

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

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

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

    【讨论】:

    • 是的 JS 出现在页面上,因为我确实是从使用应用程序布局的页面调用它。事实上,JS 不再被调用了。
    猜你喜欢
    • 2014-05-22
    • 1970-01-01
    • 2014-02-08
    • 2014-04-20
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    相关资源
    最近更新 更多