为什么rails不呈现.js.erb文件?

时间:2013-10-24 15:22:18

标签: javascript jquery ruby-on-rails

我有一个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?

4 个答案:

答案 0 :(得分: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的底部添加include helper:

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

答案 1 :(得分:5)

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

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

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

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

答案 2 :(得分:5)

抱歉,我迟到了,你可以拨打&#34; /messages/new.js.erb"使用:

消息/ new.html.erb

link_to&#34; Link&#34;,&#34;&#34;,remote:true

每当您点击该链接时,它都会触发&#34; /messages/new.js.erb"。

答案 3 :(得分:2)

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