如何在服务器端Ruby和客户端Javascript之间删除业务逻辑?

时间:2022-06-17 16:27:43

I have a Widget model with inheritance (I'm using Single-Table Inheritance, but it's equally valid for Class-per-Table). Some of the subclasses require a particular field; others do not.

我有一个带有继承的小部件模型(我使用单表继承,但它对每个表的类都同样有效)。有些子类需要一个特定的字段;别人不。

class Widget < ActiveRecord
  ALL_WIDGET_TYPES = [FooWidget, BarWidget, BazWidget]
end

class FooWidget < Widget
  validates_presence_of :color
end

class BarWidget < Widget
  # no color field
end

class BazWidget < Widget
  validates_presence_of :color
end

I'm building a "New Widget" form (app/views/widgets/new.html.erb) and would like to dynamically show/hide the color field based on a <select> for widget_type.

我正在构建一个“新小部件”表单(app/views/widgets/new.html.erb),并希望根据widget_type的

<% form_for @widget do |f| %>
  <%= f.select :type, Widget::ALL_WIDGET_TYPES %>
  <div class='hiddenUnlessWidgetTypeIsFooOrBaz'>
    <%= f.label :color %>
    <%= f.text_field :color %>
  </div>
<% end %>

I can easily write some jQuery to watch for onChange events on widget_type, but that would mean putting some sort of WidgetTypesThatRequireColor constant in my Javascript. Easy enough to do manually, but it is likely to get disconnected from the Widget model classes.

我可以轻松地编写一些jQuery来监视widget_type上的onChange事件,但这意味着在我的Javascript中放入某种WidgetTypesThatRequireColor常量。手动操作非常简单,但是很可能会从小部件模型类中断开连接。

I would prefer not to output Javascript directly in my view, though I have considered using content_for(:js) and have a yield :js in my template footer. Any better ideas?

我宁愿不直接在视图中输出Javascript,尽管我考虑过使用content_for(:js)并在模板页脚中使用yield:js。有更好的主意吗?

1 个解决方案

#1


3  

Here is the html I would generate. You could generate it from the view or helper in various ways.

这是我要生成的html。您可以通过各种方式从视图或助手生成它。

<select ...>
    <option class="widget colored">FooWidget</option>
    <option class="widget uncolored">BarWidget</option>
    <option class="widget colored">BazWidget</option>
</select>

Then have jQ watch the select and show or hide the div based on the class of the selected option.

然后让jQ根据所选选项的类监视选择、显示或隐藏div。

#1


3  

Here is the html I would generate. You could generate it from the view or helper in various ways.

这是我要生成的html。您可以通过各种方式从视图或助手生成它。

<select ...>
    <option class="widget colored">FooWidget</option>
    <option class="widget uncolored">BarWidget</option>
    <option class="widget colored">BazWidget</option>
</select>

Then have jQ watch the select and show or hide the div based on the class of the selected option.

然后让jQ根据所选选项的类监视选择、显示或隐藏div。