代码之家  ›  专栏  ›  技术社区  ›  MunkiPhD

如何在MVC应用程序中显示导航和子导航?

  •  1
  • MunkiPhD  · 技术社区  · 16 年前

    我无法确定MVC应用程序的导航位置。例如,假设您具有以下结构:

    • 会议
      • 东南会议
        • 佛罗里达大学鳄鱼队
        • 佐治亚大学斗牛犬队
        • 阿肯色州剃须刀
      • PAC-10
        • 南加州大学
        • 夏威夷
      • 大东区等。

    如何最好地创建一个结构来实现“主”导航和随后的“子”导航?使用假设的例子,您将为每个会议提供特定的子导航,显示其各自的学院(并且仅显示会议学院)。

    这是您在主视图中处理并隐藏未选定会议的内容吗? 或者你会创建一个菜单助手(或者另一个部分)并从每个学院的角度调用它?

    3 回复  |  直到 16 年前
        1
  •  1
  •   Chris Arnold    16 年前

    最好的方法是使用多个嵌套的母版页。例如,site.master将包含您的顶级导航(会议列表?)然后,每个会议都会有一个不同的母版页来“扩展”site.master。理论上,您可以拥有任意数量的嵌套母版页。最后,Florida Gator等将是“真实”视图(即非母版页)。

    棘手的部分是告诉任何父母版页当前选择了哪个导航项。由于无法将母版页绑定到ViewModel,因此必须使用视图字典,例如View[“SelectedMainnavitem”]。

        2
  •  1
  •   timdev    16 年前

    为什么不使用一些始终显示主导航并依赖某个助手呈现子导航的全局布局模板?(帮助程序可能是多余的——您可以在布局模板中直接输出子导航)

    控制器将当前类别/子类别以及一些描述当前子导航选项的数据结构传递给视图。

        3
  •  1
  •   MunkiPhD    16 年前

    在考虑了这个问题和建议之后,我提出了这个解决方案。由于我的子导航总是低于主导航,所以我决定采用常规的配置方法。

    在我的站点中。master,我有以下两个呈现部分。一个显示主导航,另一个调用BuildSubNavigation以显示获取要呈现的部分的名称:

    <% Html.RenderPartial("_MainNavigation"); %>
    <% var submenu = ViewContext.BuildSubNavigation();
        if (submenu != null) {
              Html.RenderPartial(submenu);
    }%>
    

    当然,这可以扔给一个助手,我打算这样做,这是更明确的,有助于理解这个问题。

    它的作用是调用buildSubNavigation方法。按照惯例,如果一个控制器要有一个特定的子导航,就会有一个部分以“导航”的形式出现,所以根据这个例子的精神,一个部分就是“东南会议导航”,我所做的就是检查当前视图是否真的存在。如果是这样,我将返回该名称,然后将其用于呈现部分。

    public static string BuildSubNavigation(this ViewContext vc) {
        var controller = vc.RouteData.Values["controller"] ?? "";
        var viewName = "_" + controller + "Navigation";
    
        if (ViewExists(vc.Controller.ControllerContext, viewName, null)) {
            return viewName;
        } else {
            return null;
        }
    }
    

    这是检查视图是否与当前视图引擎实际存在的方法:

    public static bool ViewExists(ControllerContext cc, string viewName, string masterName) {
        if (ViewEngines.Engines.FindView(cc, viewName, masterName).View != null) {
            return true;
        } else { return false; }
    }
    

    我不确定这是否是最好的方法,但对于我目前正在进行的一个小项目来说,它工作得相当好。

    谢谢你的回答!