【问题标题】:Apply CSS class on element if current page in Phoenix如果凤凰城的当前页面,则在元素上应用 CSS 类
【发布时间】:2015-10-12 21:22:18
【问题描述】:

如果页面处于活动状态,我目前正在寻找添加 CSS 类。目前在凤凰城最好的方法是什么?这个案子有帮手吗?

def active(option, conn) do
  if option == conn.request_path do
    " class=\"active\""
  else
    ""
  end
end

在模板中:

<%= "contact" |> active(@conn) |> raw %>

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    我们将使用conn.path_info,它以字符串列表的形式返回当前路径,而不是conn.request_path。我们可以使用它来获取我们的 active_class 助手。

    def active_class(conn, path) do
      current_path = Path.join(["/" | conn.path_info])
      if path == current_path do
        "active"
      else
        nil
      end
    end
    

    然后我们像这样使用它:

    <%= link "Users", to: user_path(@conn, :index), class: active_class(@conn, user_path(@conn, :index))%>
    

    请注意,我们在上面两次user_path/2。我们可以用另一个助手把它干掉:

    def active_link(conn, text, opts) do
      class = [opts[:class], active_class(conn, opts[:to])]
              |> Enum.filter(& &1) 
              |> Enum.join(" ")
      opts = opts
             |> Keyword.put(:class, class)
      link(text, opts)
    end
    

    为什么使用conn.path_info 而不是conn.request_path?这是因为conn.request_path 将返回用户请求的确切路径。如果用户访问路径/foo/,则conn.request_path 将返回/foo/。问题是我们将比较的路由器助手将始终返回路径/foo,而没有尾随/

    希望对您有所帮助!如果有任何不清楚的地方,请告诉我。

    【讨论】:

    • 这看起来很清晰也很简单,并且可以直接使用路径。 conn.request_path 现在在 github 上的 0.15 master 中,但它不在
    • @rockerBOO 你是对的。它在插件大师中。试过了,但我仍然建议使用conn.path_info。我会用原因更新我的答案
    【解决方案2】:

    以下代码正在与我一起工作,包括参数跟踪:

    辅助函数如下:

    def active_class(path, conn) do
      query_string = cond do
        conn.query_string == "" -> ""
        true -> "?#{conn.query_string}"
      end
      if ("#{conn.request_path}#{query_string}" === path) do "active" else "" end
    end
    

    在视图中:

    <% important_issues_path = issue_path(@conn, :index, important: true) %>
    
    <%= link "important", to: important_issues_path,
        class: "nav-link #{
          MyApp.TheHelper.active_class(important_issues_path, @conn)
       }"
    %>
    

    【讨论】:

      【解决方案3】:

      我为此创建了一个助手,如下所示:

      defmodule LinkHelper
        @doc """
        Calls `active_link/3` with a class of "active"
        """
        def active_link(conn, controllers) do
          active_link(conn, controllers, "active")
        end
      
        @doc """
        Returns the string in the 3rd argument if the expected controller
        matches the Phoenix controller that is extracted from conn. If no 3rd
        argument is passed in then it defaults to "active".
      
        The 2nd argument can also be an array of controllers that should
        return the active class.
        """
        def active_link(conn, controllers, class) when is_list(controllers) do
          if Enum.member?(controllers, Phoenix.Controller.controller_module(conn)) do
            class
          else
            ""
          end
        end
      
        def active_link(conn, controller, class) do
          active_link(conn, [controller], class)
        end
      end
      

      然后我将它导入到 web/web.ex 内部的 def view 函数中

      def view do
        ...
        import LinkHelper
        ...
      end
      

      用法:

      <li class="<%= active_link(@conn, PageController)%>"><a href="<%= page_path(@conn, :index) %>">Home</a></li>
      <li class="<%= active_link(@conn, [FooController, BarController])%>"><a href="<%= foo_path(@conn, :index) %>">Foo or Bar</a></li>
      

      【讨论】:

      • 这似乎是集成到 Controller 系统中的不错选择。您的示例代码存在一些问题。 defmodule LinkHelper doimport LinkHelper
      • @rockerBOO 好地方 - 我复制时一定忘记更新导入了!
      • 这种方法不会为您传递给它的控制器的所有操作设置一个“活动”链接吗?例如,如果您将PageController 传递给active_link/3page_path(@conn, :index)page_path(@conn, :show) 都将设置为活动状态。难道我们不希望显示页面只有在 page.show 中才“活跃”吗?
      猜你喜欢
      • 2016-05-03
      • 1970-01-01
      • 2016-09-16
      • 2018-11-27
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 2016-12-24
      • 2016-11-03
      相关资源
      最近更新 更多