仅当导航取决于控制器时布局的可用方法

问题描述 投票:0回答:2

给定一个带有导航栏的布局,该导航栏取决于当前的控制器:

# layout.html.slim
doctype html
html
  body
    main
      = render partial: 'domain_nav'
      = yield

该应用程序有几个业务领域,让我们说“客户端”,“任务”,“书籍”,具有自己独特的导航(clients_navtasks_navbooks_nav)。

每个部分都有几个控制器,视图将显示基于控制器业务域的导航(例如,Clients :: CompaniesController将显示clients_nav)。

上面的html是简化的,但基本上,所有控制器共享相同的布局,除了依赖于域的domain_nav

我看到几种方法来处理:

  • 使用帮助程序并根据控制器名称确定要使用的导航:这意味着每次引入新控制器时编辑帮助程序,它感觉不对
  • 在每个视图和content_for :navigation中使用yield :navigation:因为我们确定每个视图都显示导航,所以感觉不对
  • 每个部分使用一个子布局并调用render layout: 'clients/layout' do:它可以工作但是然后i18n变得一团糟
  • 为每个域定义一个布局:不是很干
  • 使用单一布局并定义在控制器中使用哪个导航(部分名称):使用继承设置部分名称(每个域设置一个控制器以设置导航部分名称)或关注点
  • 定义每个域的布局(在每个控制器中设置布局),但使用共享布局渲染它们,如下所示

# layouts/_shared.html.slim
doctype html
html
  body
    main
      = render partial: nav_path
      = yield

# layouts/clients.html.slim
= render partial: 'layouts/shared', locals: { nav_path: 'clients/nav' }

# layouts/tasks.html.slim
= render partial: 'layouts/shared', locals: { nav_path: 'tasks/nav' }

# layouts/books.html.slim
= render partial: 'layouts/shared', locals: { nav_path: 'books/nav' }

还有其他方法可以解决这个问题吗?你会挑选哪一个?为什么?

ruby-on-rails partials
2个回答
1
投票

如果控制器可以按其命名空间分组,就像它们的导航名称一样,我将使用"use a helper and determine which nav to use based on the controller name"方法。就像控制器名称以Clients开头一样(例如,Clients::CompaniesController),我们可以很容易地将它映射到clients_nav

def nav_path
    if params[:controller].starts_with? "Client"
        'clients/nav'
    elsif params[:controller].starts_with? "Task"
        'tasks/nav'
    else
        'books/nav'
    end
end

如果您无法通过此类命名空间对控制器进行分组,则只有拥有管理面板时,您仍然可以使用此方法的不同变体。我们可以创建一个表格,将controller_name映射到navigation_path。此表上的条目只能从管理面板填充。


0
投票

我采取了不同的方式。由于控制器负责决定布局,我认为这也是让它决定导航的轨道方式。

就像有一个“布局”声明,我现在有一个“导航”声明。这是控制器的样子:

class ClientsController < ApplicationController
  navigation 'clients/nav'
  …
end

class BooksController < ApplicationController
  navigation 'books/nav'
  …
end

而我只有一个布局:

doctype html
html
  body
    main
      = render partial: navigation
      = yield

导航方法在ApplicationController中声明:

class ApplicationController < ActionController::Base
  helper_method :navigation

  def self.navigation(path)
    define_method :navigation do
      path
    end
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.