【问题标题】:Conditionally add a class to link_to in Rails在 Rails 中有条件地向 link_to 添加一个类
【发布时间】:2014-04-18 19:19:06
【问题描述】:

我想有条件地将“隐藏”类添加到 Rails 链接标记,具体取决于是否“接受 == true”。

如果我不使用 rails link_to 我可以使用 <a href="#" class="foo bar <%= "hidden" if accepted == true %>" >。如何在 link_to 中完成此操作?

<%= link_to "Accept Friend Request", 
    "#", 
    class: "btn btn-success btn-sm btn-block requestSent ???hidden???",
    disabled: true %>

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4


    【解决方案1】:

    我已经覆盖了 link_to 以期望 class_if 参数,请查看:

    def link_to(options = {}, html_options = {})
      if html_options.is_a?(Hash) && html_options.key?(:class_if)
        html_options[:class] <<
          (" #{html_options[:class_if][1].strip}") if html_options[:class_if][0]
    
        html_options.delete :class_if
      end
    
      super(options, html_options)
    end
    

    及用法:

    &lt;%= link_to(my_path, class: "class1", class_if: [true_or_false?, 'class2']) %&gt;

    我刚刚重写了一种方法,但一个很好的重构是在此处重写所有描述的签名:http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to

    更新

    另一种解决方案是:

    module ApplicationHelper
      def active_link_to(name = nil, options = nil, html_options = nil, &block)
        html_options ||= { class: '' }
        html_options[:class].concat('is-active') if options.match(controller_name)
    
        link_to(name, options, html_options, &block)
      end
    end
    

    及用法:

    <%= active_link_to(my_path, 'My path') %>
    

    这样,即使是自定义路由,例如“my_path/help”、“my_path/two”,我也能获得“活动状态”。

    【讨论】:

      【解决方案2】:

      我在this question 上发布了类似的答案。

      更清洁的解决方案

      标准方法需要将逻辑放入视图中并使用字符串插值或将内容移动到单独的帮助程序中。

      这里有一个更新的方法可以避免这些:

      <%= link_to "Accept Friend Request", 
          "#", 
          class: class_string("btn btn-success btn-sm ban-block requestSent" => true, hidden: accepted),
          disabled: true %>
      

      class_string方法

      class_string 帮助器采用由 CSS 类名字符串布尔值组成的键/值对的散列。该方法的结果是一串类,其中布尔值评估为真。

      示例用法

      class_names("foo bar" => true, baz: false, buzz: some_truthy_variable)
      # => "foo bar baz"
      

      受 React 启发

      这项技术的灵感来自 Facebook 的 React 前端框架中名为 classNames(以前称为 classSet)的插件。

      在 Rails 项目中使用

      到目前为止,Rails 中不存在class_names 函数,但this article 向您展示了如何将其添加或实现到您的项目中。

      【讨论】:

      • 从 Rails 6.1(可能更早)开始,[token_list](github.com/rails/rails/blob/…} 方法(别名为 class_names)正是这样做的,我相信这是接受答案的更好解决方案
      【解决方案3】:

      你可以在link_to之外做:

      <% css_class = accepted ? "hidden" : "" %>
      <%= link_to "Accept Friend Request", 
        "#", 
        class: "btn btn-success btn-sm btn-block requestSent #{css_class}",
        disabled: true %>
      

      【讨论】:

        【解决方案4】:

        如果您使用带有 #{} 的插值,则您放在它之间的任何内容都将作为普通的旧 Ruby 代码运行。 在这个例子中,你可以像这样在字符串中添加一个条件类:

        <%= link_to "Accept Friend Request", 
            "#", 
            class: "btn btn-success btn-sm btn-block requestSent #{'hidden' if accepted}",
            disabled: true %>
        

        请注意,您应该在类名“hidden”周围使用单引号。 另请注意,当变量表示布尔值(true 或 false)时,您无需明确表示 if accepted == true。你可以简单地说if accepted

        【讨论】:

        • 伟大、优雅和最简单的解决方案。谢了!
        • 这应该是 IMO 接受的答案。例如,如果您有一个包含 5 个链接的导航,并且您想要添加一个类来突出显示 current_page,那么您无法使用已接受的答案来执行此操作。但这个答案就像一个魅力!
        【解决方案5】:

        您也可以使用帮助程序来建立链接:

        def accept_friend_request_link
          classes = [:btn, :and_friends]
          if accepted
            classes << :hidden
          end
          link_to 'Accept Friend Request', '#', class: classes, disabled: true
        end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-02-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-16
          • 1970-01-01
          相关资源
          最近更新 更多