8

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

消息控制器.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?

4

4 回答 4

8

为什么这行不通?

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

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

解决方案1:在每个页面上加载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" %>
于 2013-10-24T15:44:23.580 回答
5

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

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

动作的respond_to块的目的是html请求(经典浏览)和js请求时使用js,这就是你用于ajax的。

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

于 2013-10-24T15:45:49.707 回答
5

抱歉,我迟到了,但您可以使用以下命令调用“/messages/new.js.erb”中的 JavaScript:

消息/new.html.erb

link_to "Link", "", remote: true

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

于 2016-06-14T19:21:57.957 回答
2

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

于 2017-04-20T17:27:45.807 回答