【问题标题】:Why is rails not rendering the .js.erb file?为什么 rails 不渲染 .js.erb 文件?
【发布时间】:2013-10-24 15:22:17
【问题描述】:

我有一个 Rails 应用程序,我试图让 jQuery 使用 HTML 文件进行渲染。关键是 jQuery 是特定于页面的,所以我不希望通过将它放在页眉中来为每个页面加载它。这是我对文件所做的处理

messages_controller.rb

 # GET /messages/new
 def new
    @message = Message.new
    @users = User.where('id != ' + current_user.id.to_s)
    #if @message.save
       #MessageMailer.new_message(@message).deliver

    respond_to do |format|
       format.html # new.html.erb
       format.js
    end
    #end
 end

/messages/new.html.erb

<div class="row">
    <div class="large-12 columns">
        <div class="panel">
            <h1>New message</h1>
            <%= render 'form' %>

            <%= link_to 'Back', messages_path, :class => "button small" %>
        </div>
    </div>
</div>

/messages/new.js.erb

$("h1").html('hello'); //for testing that it works

有什么我必须添加到另一个文件中的吗?有没有我必须提出的请求才能同时加载 HTML 和 .js?

【问题讨论】:

  • 除了答案,您还应该阅读这篇文章:stackoverflow.com/questions/6167805/…
  • 这是不安全的User.where('id != ' + current_user.id.to_s)。请改用User.where('id != ?', current_user.id.to_s)

标签: javascript jquery ruby-on-rails


【解决方案1】:

为什么这不起作用?

我不认为您的方法是实现您想要的特别标准的方法。未加载 JS 模板的原因是,如果浏览器请求 HTML,则控制器设置为响应 HTML 模板,如果浏览器请求 JS,则响应 JS 模板。它永远不会返回两者,因为浏览器只能请求一个或另一个。

换句话说,控制器中的 respond_to 块指示控制器如何响应对不同类型内容的请求,而不是在每个请求中列出将要发送的所有类型的内容。

方案一:每页加载JS

这里有几件事需要考虑。首先,仅仅因为 JS 没有在特定页面上使用,本身并不是不加载它的好理由。 Rails 通过 Sprockets 将所有 JS 连接并压缩到一个文件中。只要这个文件没有改变,它就会被用户的浏览器缓存。当您的用户访问需要此 JS 的页面时,这将导致更快的响应,因为它不需要发出额外的请求来获取新的 JS。

如果您担心您的 JS 在不应该运行的内容上运行,那么您真的应该通过向您希望它运行的一个或多个页面添加唯一标识符来防止这种情况,然后检测到JS 中的标识符。例如:

$("h1.special").html('hello');

解决方案 2:使用 content_for

但是,在某些情况下,单独加载 JS 可能会有所帮助。在我看来,实现这一点的最佳方式是,如果个别视图需要,则使用块内容将内容附加到您的头部。

所以在你的应用布局中:

#layouts/application.html.erb
<head>
  #Other head content here

  <% if content_for?(:head) %>
    <%= yield(:head) %>
  <% end %>

  #Other head content here
</head>

#messages/new.html.erb
<% content_for :head do $>
  <%= javascript_include_tag "messages_new.js" %>
<% end %>
#Other view stuff here

#assets/messages_new.js
$("h1").html('hello');

messages_new.js 将仅包含在包含该 content_for 块的视图上,并因此运行。它不应出现在任何其他页面上。

解决方案 3:只需在 html 中包含 javascript

或者,如果您不关心 JS 是否最后加载,那么您可以在 new.html.erb 的底部添加包含帮助器:

#messages/new.html.erb
#Other view stuff here
<%= javascript_include_tag "messages_new.js" %>

【讨论】:

    【解决方案2】:

    据我了解,您希望在请求 /messages/new 时提供 new.html 和 new.js。

    它不起作用,rails 控制器将使用 js 或 HTML,并且永远不会同时使用两者。 HTTP 不能那样工作。您只有一个响应 HTTP 请求而发送的文件,并且您不能同时发送 2 个。

    action的respond_to块的目的是html请求时使用html(经典浏览),js请求时使用js,ajax就是这样用的。

    你想要什么,你需要在你的erb中添加一个js引用,没有别的办法。

    【讨论】:

      【解决方案3】:

      对不起,我迟到了,但您可以使用以下方法调用“/messages/new.js.erb”中的 JavaScript:

      消息/new.html.erb

      link_to "Link", "", remote: true
      

      任何时候您点击该链接都会触发“/messages/new.js.erb”。

      【讨论】:

        【解决方案4】:

        如果您将 html.erb 文件包装在脚本标签中,Javascript 代码将从该文件运行。如果它仅用于测试目的并且只是临时的,这可能是一种使用 html 触发 jquery 的快速简便的方法,而不是创建一个新的单独文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-01-12
          • 2011-08-21
          • 1970-01-01
          • 2021-03-21
          • 2016-12-30
          • 2013-07-06
          • 2023-03-11
          相关资源
          最近更新 更多