javascript 为什么 rails 不渲染 .js.erb 文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19570024/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is rails not rendering the .js.erb file?
提问by nwestfall
I have a rails application where I am trying to have jQuery render WITH an HTML file. The point of this is that the jQuery is specific to the page so I don't want it loading for every page by putting it in the header. Here's what I have done to the files
我有一个 rails 应用程序,我试图在其中使用 HTML 文件渲染 jQuery。重点是 jQuery 特定于页面,因此我不希望通过将其放在标题中来为每个页面加载它。这是我对文件所做的
messages_controller.rb
消息控制器.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
/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
/messages/new.js.erb
$("h1").html('hello'); //for testing that it works
Is there something that I have to add to another file? Is there a request I have to make so it loads both the HTML and .js?
有什么我必须添加到另一个文件中的吗?是否有我必须提出的请求,以便它同时加载 HTML 和 .js?
回答by Rupert Madden-Abbott
Why this won't work?
为什么这行不通?
I don't think your method is a particularly standard way to accomplish what you want. The reason why your JS template is not being loaded is because your controller is setup to respond with an HTML template, if the browser requests HTML, and a JS template, if the browser requests JS. It will never return both because the browser can only request one or the other.
我不认为你的方法是完成你想要的特别标准的方法。你的 JS 模板没有被加载的原因是因为你的控制器设置为响应 HTML 模板,如果浏览器请求 HTML,如果浏览器请求 JS,则响应一个 JS 模板。它永远不会返回两者,因为浏览器只能请求其中一个。
In other words, the respond_to block in your controller is instructing the controller how to respond to requests for different types of content, not listing all of the types of content that will be sent, on every request.
换句话说,您的控制器中的 respond_to 块指示控制器如何响应对不同类型内容的请求,而不是在每个请求中列出将发送的所有内容类型。
Solution 1: Load the JS on every page
解决方案1:在每个页面上加载JS
There are a couple of things to consider here. Firstly, just because JS is not used on a particular page, is not, in itself, a good reason not to load it. Rails, via Sprockets, will concatenate and minify all of your JS into a single file. As long as this file does not change, then it will be cached by a user's browser. This will result in a faster response when your user visits a page that does require this JS, as it won't need to make an extra request in order to get the new JS.
这里有几件事情需要考虑。首先,仅仅因为 JS 不在特定页面上使用,本身并不是不加载它的好理由。Rails 通过 Sprockets 将您的所有 JS 连接并缩小到一个文件中。只要这个文件没有改变,它就会被用户的浏览器缓存。当您的用户访问确实需要此 JS 的页面时,这将导致更快的响应,因为它不需要发出额外的请求来获取新的 JS。
If you are concerned about your JS running on content that it shouldn't, then you should really be guarding against this by adding a unique identifier to the page, or pages, on which you want it to run, then detecting that identifier in your JS. For example:
如果您担心您的 JS 在它不应该运行的内容上运行,那么您真的应该通过向您希望它运行的一个或多个页面添加一个唯一标识符来防范这种情况,然后在您的JS。例如:
$("h1.special").html('hello');
Solution 2: Use content_for
解决方案 2:使用 content_for
However, there are some circumstances in which it might be beneficial to load JS separately. The best way to accomplish that, in my opinion, is to have a content for block that appends content to your head, if an individual view needs it.
但是,在某些情况下,单独加载 JS 可能是有益的。在我看来,实现这一点的最佳方法是为块添加内容,如果单个视图需要,则将内容附加到您的头脑中。
So in your application layout:
所以在你的应用程序布局中:
#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 will then only included, and therefore run, on views where you include that content_for block. It should not appear on any other page.
然后,messages_new.js 将仅包含并运行在包含该 content_for 块的视图上。它不应出现在任何其他页面上。
Solution 3: Just include the javascript in your html
解决方案 3:只需在您的 html 中包含 javascript
Alternatively, if you don't care if the JS is loaded last, then you can just add the include helper at the bottom of the new.html.erb:
或者,如果您不关心 JS 是否最后加载,那么您可以在 new.html.erb 的底部添加包含帮助程序:
#messages/new.html.erb
#Other view stuff here
<%= javascript_include_tag "messages_new.js" %>
回答by Syl
From what i understand, you want to have new.html and new.js to be served when requesting /messages/new.
据我了解,您希望在请求 /messages/new 时提供 new.html 和 new.js。
It will not work, the rails controller will use js or HTML and never both. HTTP does not work like that. You have only one file that is send in response to an HTTP request and you cannot send 2 at the same time.
这是行不通的,rails 控制器将使用 js 或 HTML,从不使用两者。HTTP 不是那样工作的。您只有一个响应 HTTP 请求而发送的文件,并且您不能同时发送 2 个。
The purpose of the respond_to block of the action is to use html for html request (classic browsing) and js when the request is for js, and that's what you use for ajax.
action的respond_to块的目的是为了html请求(经典浏览)使用html,请求js时使用js,这就是ajax使用的。
For what you want, you need to add a js reference in your erb, there is no other way.
对于你想要的,你需要在你的erb中添加一个js引用,没有其他方法。
回答by kizziah
Sorry I'm late but you can call the JavaScript in "/messages/new.js.erb" by using:
抱歉,我迟到了,但您可以使用以下命令调用“/messages/new.js.erb”中的 JavaScript:
messages/new.html.erb
消息/new.html.erb
link_to "Link", "", remote: true
Any time you click that link it will fire "/messages/new.js.erb".
任何时候单击该链接时,它都会触发“/messages/new.js.erb”。
回答by PJL
Javascript code will run from your html.erb file if you wrap it in script tags. If it's for testing purposes only and just temporary, this might be a quick and easy way to fire your jquery with your html rather than creating a new, separate file.
如果您将 html.erb 文件包装在脚本标签中,Javascript 代码将从您的 html.erb 文件中运行。如果它仅用于测试目的并且只是临时的,那么这可能是一种使用 html 触发 jquery 的快速简便的方法,而不是创建一个新的单独文件。