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

nwe*_*all 8 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
Run Code Online (Sandbox Code Playgroud)

/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>
Run Code Online (Sandbox Code Playgroud)

/messages/new.js.erb

$("h1").html('hello'); //for testing that it works
Run Code Online (Sandbox Code Playgroud)

有什么东西我必须添加到另一个文件?是否有我要做的请求,所以它加载HTML和.js?

Rup*_*ott 9

为什么这不起作用?

我不认为你的方法是一种特别标准的方法来实现你想要的.你的JS模板没有被加载的原因是因为你的控制器被设置为响应HTML模板(如果浏览器请求HTML)和JS模板(如果浏览器请求JS).它永远不会返回,因为浏览器只能请求其中一个.

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

解决方案1:在每个页面上加载JS

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

如果你担心你的JS运行在它不应该运行的内容上,那么你应该通过向页面或页面添加一个唯一的标识符来防止这种情况发生,然后检测你的标识符. JS.例如:

$("h1.special").html('hello');
Run Code Online (Sandbox Code Playgroud)

解决方案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');
Run Code Online (Sandbox Code Playgroud)

然后,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" %>
Run Code Online (Sandbox Code Playgroud)


Syl*_*Syl 5

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

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

response_to块的作用是使用html进行html请求(经典浏览)和js,当请求是js时,这就是你用于ajax的内容.

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


小智 5

对不起,我迟到了,你可以用"/messages/new.js.erb"调用JavaScript:

消息/ new.html.erb

link_to"Link","",remote:true

只要您点击该链接,它就会触发"/messages/new.js.erb".