【问题标题】:Use helpers to clarify code使用助手来澄清代码
【发布时间】:2017-08-18 22:08:30
【问题描述】:

我有一个很大的注册表单,所以我只是给你看一个“小”部分。

<div class="input-element uk-margin-small-bottom uk-flex">
  <% if @user.errors[:first_name].any? %>
    <div class="uk-inline uk-width-1-2" title="<%= @user.errors[:first_name].first %>" uk-tooltip="pos: left">
      <span class="uk-form-icon" uk-icon="icon: user"></span>
      <%= f.text_field :first_name, placeholder: "First name", class: "uk-input uk-form-danger" %>
    </div>
  <% else %>
    <div class="uk-inline uk-width-1-2">
      <span class="uk-form-icon" uk-icon="icon: user"></span>
      <%= f.text_field :first_name, placeholder: "First name", class: "uk-input" %>
    </div>
  <% end %>
</div>

这是每个输入的逻辑,并且架构是相同的:

  • 在字段出现错误的部分添加工具提示
  • 添加一个 CSS 类来区分有无错误的字段

它导致大量 HTML / Ruby 代码用于相同的通用机制。我知道 Rails 提供了一些帮助程序来简化某些场景中的代码。

我的问题可以通过助手解决吗?如果可以,您认为我应该如何处理?

谢谢,

【问题讨论】:

  • 您正在验证模型中所需的字段?您应该会出现一些错误,这可能是最容易调整的。
  • @RockwellRice 不确定我的解释是否不清楚,但从代码的角度来看没有问题。一切正常,错误消息显示正确。我唯一的问题是代码的可读性,我感觉在字段之间重复我自己。 如何提高助手的可读性?

标签: ruby-on-rails ruby


【解决方案1】:

我想说你可能是在partial 而不是helper

我会制作一个名为例如:_form_field.html.erb 的部分内容,例如:

<div class="input-element uk-margin-small-bottom uk-flex">
  <% 
  if model.errors[:field].any?
    title = model.errors[:field].first
    tooltip = 'pos: left'
    input_extra_class = 'uk-form-danger'
  else
    title = '' 
    tooltip = ''
    input_extra_class = ''
  end
  %>
  <div class="uk-inline uk-width-1-2" title="<%= title %>" uk-tooltip="<%= tooltip %>">
    <span class="uk-form-icon" uk-icon="icon: user"></span>
    <%= f.text_field :field, placeholder: label, class: "uk-input <%= input_extra_class %>" %>
  </div>
</div>

然后这样称呼它:

<%= render 'form_field', model: @users, field: :first_name, label: 'First name' %>

请注意,在部分内容中,我已将发生变化的位提取到 if 语句中,以避免重复不变的 html 标记。这是可选的......如果你愿意,你可以保持原样。但无论哪种方式,在您将modelfieldlabel 作为局部变量传递的地方进行部分设置。

这是关于部分的 rails doco:http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials

【讨论】:

  • 请注意,您可以使用字段数组快速调用它,例如:&lt;% [:first_name, :last_name, other_field].each do |field| %&gt;,然后将调用行更改为&lt;%= render 'form_field', model: @users, field: field, label: field.to_s.humanize %&gt;。当然还有&lt;% end %&gt; 之后。
  • 谢谢,解决方案有效。然而,我发现了另一种通过局部变量传递变量的方法 (stackoverflow.com/questions/6672454/…),我认为它效果更好。
【解决方案2】:

我认为部分可能更清洁,但您仍然可以使用助手,可能是这样的:

助手

def my_text_field(errors, element)
  div_options = { class: "uk-inline uk-width-1-2" }
  input_class = "uk-input"

  if errors.any?
    div_options.merge(title: errors.first, "uk-tooltip": "pos: left")
    input_class << " uk-form-danger"
  end

  content_tag(:div, div_options) do
    content_tag(:span, class: "uk-form-icon", "uk-icon": "icon: user") do
      element.text_field :first_name, placeholder: "First name", class: input_class
    end
  end
end

查看

<div class="input-element uk-margin-small-bottom uk-flex">
  <%= my_text_field(@user.errors[:first_name], f) %>
</div>

【讨论】:

    猜你喜欢
    • 2020-08-22
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-18
    • 2021-12-06
    • 1970-01-01
    • 2015-08-17
    相关资源
    最近更新 更多