使用方法的一个(小)缺点是,当简单地将块传递给 tldr 时,任何默认输入 html 选项(如简单表单或类或属性)和任何默认选项(如 )都会f.input do end
丢失required
:optional
输入required
不会被修饰。b.use :input, class: 'input-element'
f.input
如果您依赖这些额外的类和属性,则必须手动传递它们(不是干的)。
为了克服这个问题,我为我的特殊选择创建了一个自定义输入,所以我可以像我想要的那样定义我的选择主体(<option>
标签),但是选择像往常一样被装饰:
# app/inputs/select_container_input.rb
class SelectContainerInput < SimpleForm::Inputs::Base
def input(wrapper_options)
options_html = input_options.delete(:options_html)
# since we pass our options by our self (and have to select the correct
# option), set `selected` to `''` to prevent rails calling
# `object.send(attribute_name)` only to set `selected` which is not used.
input_options[:selected] = ''
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
@builder.select attribute_name, nil, input_options, merged_input_options do
options_html
end
end
end
简单地这样称呼它:
<% options_html = capture do %>
<option>bla</option>
<% end %>
<%= f.input :attribute, as: :select_container, options_html: options_html %>
这options_html
是一种解决方法,因为实际上将块传递给我们的自定义输入会更容易:
<%= f.input :attribute, as: :select_container do %>
<option>bla</option>
<% end %>
但是由于SimpleForm::FormBuilder#def_input的工作方式,该块在代码甚至触及输入之前就被带走了。所以没有办法不重构 simple_form。
总而言之,这通过在您的视图中为您的特殊选择添加一点额外嘈杂的代码来解决问题。