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

发布于 2024-08-05 10:43:24 字数 378 浏览 3 评论 0原文

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

  • 会议
    • 东南会议
      • 佛罗里达鳄鱼队
      • 乔治亚斗牛犬
      • 阿肯色剃刀鲸队
    • 太平洋十校联盟
      • 南加州大学
      • 夏威夷
    • 大东等...

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

您是否会在主视图中处理此问题并隐藏未选定的会议? 或者您会创建一个菜单助手(或另一个部分)并从每个大学的视图中调用它?

I'm having trouble determining where to place navigation for an MVC app. For example, say you have the following structure:

  • Conferences
    • South Eastern Conference
      • Florida Gators
      • Georgia Bulldogs
      • Arkansas Razorbacks
    • Pac-10
      • USC
      • Hawaii
    • Big East etc...

How would you best create a structure for implementing a 'main' navigation and subsequent 'sub' navigation? Using the hypothetical example, You'd have specific sub navigation for each conference, showing its respective colleges (and only that conferences colleges).

Is this something you'd handle in the main view and just hide the non-selected conference?
Or would you create a menu helper (or yet another partial) and call that from each individual college's view?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

携君以终年 2024-08-12 10:43:25

在考虑了这个问题一段时间以及建议后,我想出了这个解决方案。由于我的子导航始终位于主导航下方,因此我决定采用约定优于配置的方法。

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

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

当然,这可以扔到一个 Helper 中,我打算这样做,这更明确并且有助于理解的问题。

它的作用是调用 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;
    }
}

这是检查视图是否确实存在于当前视图引擎中的方法:

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

我不确定这是否是执行此操作的最佳方法,但它对于我当前正在进行的小项目来说效果相当好。

感谢您的回答!

After contemplating this issue for a while along with the suggestions, I came up with this solution. Since my subnavigation will always be below the main navigation, I decided to go with the Convention over Configuration method.

In my Site.Master, I have the following two render partials. One displays the main navigation and the other makes a call to BuildSubNavigation to display get the name of a partial to render:

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

Granted, this could be thrown into a Helper, and I intend to do that, this is more explicit and aids in the understanding of the issue.

What this does is call the BuildSubNavigation method. It goes with the convention that if a controller is to have a specific sub navigation, there will be a partial in the form of "_Navigation" So in the spirit of the example, one partial would be "_SouthEasternConferenceNavigation" What I do is then check to see if the current view actually exists. If it does, I return the name, where it's then used to render the partial.

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

And this is the method that checks whether the View actually exists against the current 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; }
}

I'm unsure if this is the best way to do this, but it's working rather well for a small project I'm currently working on.

Thanks for the answers!

把时间冻结 2024-08-12 10:43:24

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

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

Best way is to use multiple, nested master pages. e.g. Site.master would contain your top-level nav (list of conferences?) then you'd have a different master page for each conference that would 'extend' site.master. You can, in theory, have as many nested master pages as you want. Finally, Florida Gators etc would be 'real' views (i.e. non-master pages).

The tricky part is telling any parent master page which navigation item is currently selected. Because you can't bind master pages to the ViewModel you'll have to use the View Dictionary e.g. View["SelectedMainNavItem"].

听风吹 2024-08-12 10:43:24

为什么不使用一些始终显示主导航的全局布局模板,并依赖一些助手来呈现子导航? (助手可能是多余的——您可能只是在布局模板中输出内联的子导航​​)

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

Why not use some global layout template that always displays the main navigation, and relies on some helper to render the subnav? (The helper may be superfluous -- you might just output the subnavigation inline in the layout template)

Your controller passes current category/sub-category, and some data structure describing the current subnavigation options, to the view.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文