如何将内联 ruby 代码与我的客户端 RJS 混合使用?

How can I mix inline ruby code with my client side RJS?

我正在使用 PrivatePub,但我遇到了一些奇怪的行为。在查看详细信息之前,请注意我使用的是 Ruby 1.9.3 和 Rails 3.2.2.

假设我有 TestsController:

class TestsController < ApplicationController
  def index
  end

  def create
    respond_to do |format|
      format.js
    end
  end
end

tests/index.html.erb

<h1>Test</h1>

<%= content_for :footer do %>
  <%= subscribe_to tests_path  %>
<% end %>

tests/create.js.erb

<% publish_to tests_path do %>
  alert("Working fine");

  if (false) {alert("This never run");};

  if (false) {<% puts "*"*100 %>};

<% end %>

简单明了。现在我的问题是,每当我 运行 create 操作时,出于某种原因 <% puts "*"*100 %> 总是 运行 (即使我做了 if(false) 语句)。

我知道我可以只使用 ruby if 然后应该可以正常工作,比如:

  <% if false %>
    <% puts "*"*100 %>
  <% end %>

但我仍然想做一些客户端验证(例如检查 div 是否存在,然后相应地渲染一些部分),如:

if ($("#chat").length){
  $("#chat").append("<%= j render(@messages) %>");
}

但似乎 <%= j render(@messages) %> 会一直呈现。

如何解决这个问题并使用客户端 if 语句和 ruby 模板代码?目前看来 <%%> 内的任何内容都会被触发,我不希望出现这种情况。

puts "*"*100 总是被打印出来,因为在你的 js.erb 文件的处理过程中,文件中的所有 Ruby 代码都会被执行。

JavaScript代码仅在浏览器中运行时才会执行,因此if (false)语句在文件的ERB处理过程中无效。

因此,这与 PrivatePub gem 无关,但这是因为您混合了 JS 和 Ruby 代码。

对于您最后一个(聊天)代码示例,请尝试 render_to_string,但这可能还不够,因为 @messages 变量在编译 JS 文件期间为空。

我想补充一点,混合使用 JS 和 Ruby 会导致一些麻烦。有时最好在视图文件中用 Ruby/ERB 在 HTML 元素上设置数据属性,然后让 JS 代码读取和使用这些数据属性的值。这样您就不必在 JS 代码中使用 Ruby 代码。