在 Ruby on Rails 上使用 javascript 注入 ruby

Posted

技术标签:

【中文标题】在 Ruby on Rails 上使用 javascript 注入 ruby【英文标题】:Injecting ruby with javascript on Ruby on Rails 【发布时间】:2020-10-08 17:50:05 【问题描述】:

所以,我想做的事情是有一个按钮,将更多字段添加到表单中。假设我有这个:

<div class="row">
      <div class="form-group string required">
        <div class="cep_filter">
          <div class="col-md-3 traffic-columns">
            <%= f.input :condition, collection: @traffic_columns, label: "Monitor (*)" %>
          </div>
          <div class="col-md-1">
            <%= f.input :operator, collection: @operator, label: "Op (*)" %>
          </div>
          <div class="col-md-2">
            <%= f.input :filter, label: "Value (*)",input_html: type: "text"  %>
          </div>
        </div>
        <div class="col-md-3">
          <%= f.input :window, collection: @window, label: "Window Type", input_html: type: "text" %>
        </div>
        <div class="col-md-3">
          <%= f.input :window2, label: "Window Value", input_html: type: "text" %>
        </div>
      </div>
    </div>

然后,假设我有一个这样的按钮:

<%= link_to content_tag(:i, nil, class: "fa fa-plus"),
             '', style: 'color: green', class: "btn btn-small add-new-condition", 'data-backdrop' => "static" %>

我想要做的是,当你点击那个按钮时,你称之为:

$(document).on("click", ".add-new-condition", function(e) 
  var html =
  "<div class='col-md-3 traffic-columns'> \
    <%= f.input :new_param, collection: @traffic_columns, label: 'Monitor (*)' %>\
  </div>
  "
);

然后将该 html 附加到某个 div 元素。根据我的阅读,不可能从 javascript 注入 ruby​​。它与一个服务器端和另一个客户端有关。我已经尝试过了,ruby 代码显示为字符串。我可以使用纯 html 来构建这些新字段,比如等等,但这里重要的是,我想添加稍后我可以在控制器中访问的新字段,例如新字段,params[:new_param]

有没有办法只使用 html 添加新字段,以便稍后在我的 rails 控制器中访问输入的值?谢谢。

【问题讨论】:

您可以拨打ajax 来完成。使用 ajax,客户端可以从服务器获取所需的 HTML 元素字符串,然后您可以将接收到的字符串插入到您需要的 DOM 中。 可能最简单的方法是将流量列字段加载到页面上,但最初将其隐藏。然后只需使用 JS 切换可见性。您当前的方法不起作用,因为浏览器无法执行 Ruby,因此它不知道如何处理整个 &lt;%=f.input。请记住,当您从服务器发送视图 HTML 时,它会经过 Ruby/ERB 预处理器步骤,而这里不会发生这种情况 无论何时点击提交,只要您提交表单,所有具有名称的元素都应放入params[:name]。我假设您在提交之前也不需要控制器中的数据。 【参考方案1】:

查看Working with JavaScript in Rails 指南,特别是有关如何使用一些 JavaScript 从您的 Rails 服务器响应然后由客户端评估的部分(“rails-ujs”)。

这为您提供了所需的所有功能(并且可以替代现在人们使用整个 JS 框架的很多功能,顺便说一句)

您所需要的只是link_to ... remote: true 到一个由控制器操作处理的路径,该控制器操作可以respond_to ... format.js。然后将something.js.erb 文件放入app/views 文件夹中的正确位置,Rails 会为您完成剩下的工作。

如果您仍有疑问,请仔细查看完整指南以获取完整图片并在下方发表评论。我很乐意扩展我的答案!

【讨论】:

这个答案是我所需要的,虽然我喜欢下面的答案,但对我来说,这会让我的生活更轻松。谢谢!【参考方案2】:

你已经非常成功了!

您是否将文字字符串 <%= f.input :new_param, collection: @traffic_columns, label: 'Monitor (*)' %> 注入到您的 div 中,而您想要的看起来更像 &lt;input type="text" /&gt;

这是因为 ruby​​ 服务器会将 ERB 代码转换为 HTML。

您似乎已经在您的 ERB 中使用&lt;%= f.input :condition, collection: @traffic_columns, label: "Monitor (*)" %&gt; 创建了一个输入字段。给包装的 div 一个 id 以便表单包含它作为第一个字段:

<div class="col-md-3 traffic-columns" id="duplicate_and_inject_this">
            <%= f.input :condition, collection: @traffic_columns, label: "Monitor (*)" %>
          </div>

然后,在 click 事件中,克隆该 div 并将其附加到您想要的任何位置。

$(".add-new-condition").click(function ()
  var new_input = $("#duplicate_and_inject_this").clone();
  new_input.appendTo( "#new_inputs_wrapper" );
)

这样,ruby 会为您呈现输入字段,而 JS 会在您单击按钮时复制该输入字段的次数。

如果您想从零个输入实例开始,只需像其他人提到的那样将其隐藏,然后在克隆后使其可见。

您可以通过其他方式更改克隆,以更新新的 name 属性或在将其附加到表单之前更改其值。

如果按照其他建议,您要使用link_to remote,则每次添加字段时都必须进行服务器调用。克隆 HTML 并用 JS 注入它会快得多。

【讨论】:

没有将此作为答案,但也非常有用,因为我想在我的部分中添加更多字段。唯一的问题是,在这种情况下,您正在克隆具有相同参数名称 (:condition) 的字段,因此稍后在控制器中,您将在 params[:condition] 中有多个值。 您可以在附加之前更改克隆元素中的名称参数。 new_input.attr(‘name’, ‘new_name_param’); 应该做你需要的。 虽然我完全理解您是否希望 Rails 控制器负责命名参数。只需为未来的读者或改变主意添加 JS 解决方案即可。

以上是关于在 Ruby on Rails 上使用 javascript 注入 ruby的主要内容,如果未能解决你的问题,请参考以下文章

在 Ruby on Rails 上使用 javascript 注入 ruby

如何将 HSQLDB 与 Ruby on Rails 一起使用。

如何在我的 Ruby on Rails 应用程序上使用 ruby​​ 2.7

如何在 ruby​​-on-rails 应用程序上使用 Rack 发送 POST 模拟请求?

Coffeescript 和 jQuery 无法在特定视图上使用 Ruby on Rails

Windows 中的 Jenkins 和 Ruby On Rails 4