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

时间:2009-09-20 19:50:22

标签: model-view-controller navigation

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

  • 会议
    • 东南会议
      • Florida Gators
      • Georgia Bulldogs
      • Arkansas Razorbacks
    • 太平洋10
      • USC
      • 夏威夷
    • Big East等......

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

这是你在主视图中处理的东西,只是隐藏未选择的会议? 或者你会创建一个菜单助手(或者另一部分)并从每个学院的视图中调用它?

3 个答案:

答案 0 :(得分:1)

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

棘手的部分是告诉任何父母主页面当前选择了哪个导航项目。因为您无法将母版页绑定到ViewModel,所以您必须使用查看字典,例如视图[ “SelectedMainNavItem”]。

答案 1 :(得分:1)

为什么不使用一些总是显示主导航的全局布局模板,并依赖一些帮助来渲染子窗体? (帮助器可能是多余的 - 您可能只是在布局模板中输出内联导航)

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

答案 2 :(得分:1)

在考虑了这个问题一段时间后,我提出了这个解决方案。由于我的子导航将始终低于主导航,我决定采用Convention over Configuration方法。

在我的Site.Master中,我有以下两个渲染部分。一个显示主导航,另一个调用BuildSubNavigation显示获取部分渲染的名称:

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

当然,这可能会被投入帮助者,我打算这样做,这更明确,有助于理解这个问题。

这样做是调用BuildSubNavigation方法。它跟惯例,如果一个控制器有一个特定的子导航,也将在“_Navigation”在例子中的精神,一个部分将是一种形式的局部“_SouthEasternConferenceNavigation”我要做的就是再检查查看当前视图是否确实存在。如果是,我返回名称,然后用它来渲染部分名称。

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;
    }
}

这是检查View是否实际存在于当前View Engine中的方法:

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

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

感谢您的回答!