Mvc 动态菜单填充纯文本 [英] Mvc Dynamic Menu Populating plain text

查看:16
本文介绍了Mvc 动态菜单填充纯文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了创建菜单的第 N 级动态菜单递归方法.

如上图所示,内容返回到名为_Menu.cshtml"的 ParialView 并且这个 Partial View 文件是空的.

然后是_LayoutPage.Cshtml

 <头><meta name="viewport" content="width=device-width"/><title>@ViewBag.Title</title><身体><div><div><input type="text" id="txtSearch"/><button id="btnSearch">搜索</button>

<div id="菜单">@{Html.RenderAction("_Menu", "Home");}@Html.Partial("_Menu")

<div>@RenderBody()

它成功地将结果放入浏览器,但作为我上面提到的纯文本,可以在下面看到.

我怎样才能让这些行为像链接一样,而不是像明文一样?帮助将不胜感激.谢谢:)

解决方案

我对这个问题的看法稍微复杂一些.

在我放置的布局中......

 @if (Model != null && Model is Core.Objects.Entities.CMS.Page){@Html.Action("Menu", new MenuOptions { IsRootMenu = true, ForPageId = Model.Id, Depth = 3 })}

我首先检查用户是否已登录并因此在托管页面上",这仅在模型属于特定类型Core.Objects.Entities.CMS.Page"时才会发生.

然后我调用@Html.Action,它在我的控制器上调用以下子操作,并构建我的菜单选项......

[HttpGet][ChildActionOnly][路线(〜/菜单")]公共 ActionResult 菜单(MenuOptions 选项){//TODO:考虑其他复杂的菜单场景,如基于弹出/树的结构//可能需要新的 api 调用来支持更复杂的菜单场景//TODO:弄清楚如何构建这些,也许使用字符串构建器var expand = string.Empty;如果(选项.深度> 0){开关(选项.深度){情况 1: expand = "?$expand=PageInfo,Pages($expand=PageInfo)";休息;情况 2: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo))";休息;case 3: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo)))";休息;case 4: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=Pages($expand=PageInfo))))";休息;案例5:expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo)))))";休息;}}var query = options.IsRootMenu?"Core/Page/MainMenuFor(id=" + options.ForPageId + ")" + 展开: "Core/Page/ChildrenOf(id=" + options.ForPageId + ")" + 展开;var items = Task.Run(() => Api.GetODataCollection(query)).Result;返回 PartialView(new MenuViewModel { Origin = options.ForPageId, Pages = items });}

就我而言,这个区域需要做一些工作,我可能应该用一些构建查询的更智能的循环代码替换那个 case 语句.

简而言之,尽管这一切都是将页面对象的层次结构从我的 OData API 中拉出到由我传入的选项决定的深度,因为菜单往往会有所不同,有些是单级选项,有些是多级,但我想要一个可重用的菜单系统.

完成后,我可以获取 OData 结果并为菜单视图构建一个模型,看起来像这样......

@model MenuViewModel@if (Model.Pages != null){<ul class="菜单">@foreach(Model.Pages 中的 var p){Html.RenderPartial("MenuItem", new MenuItemViewModel { Page = p, Origin = Model.Origin });}}

菜单视图为根目录设置一个列表并为每个子页面渲染一个子页面,我计划在某个时候扩展这个视图,例如吐出可能在我拉入控制器的 OData 结果中的父页面.

最后一块拼图是菜单项视图,它处理渲染每个单独的菜单项......

@model MenuItemViewModel<li><a href="@Html.Raw("/" + Model.Page.Path)" @CurrentItem(Model.Page)>@Html.PageInfo(Model.Page).Title</a>@if (Model.Page.Pages != null && Model.Page.Pages.Any()){<ul class="子菜单">@foreach(Model.Page.Pages 中的 var p){Html.RenderPartial("MenuItem", new MenuItemViewModel { Page = p, Origin = Model.Origin });}}@职能{MvcHtmlString CurrentItem(Core.Objects.Entities.CMS.Page p){if (Model.Origin == p.Id) return new MvcHtmlString("class='selected'");返回空;}}

完成所有这些后,我最终得到了一组嵌套的列表,然后我使用 CSS 来处理弹出窗口或动态扩展等内容.

这个功能不是很完整,我需要确保我用一个类或其他东西来处理标记当前项目",这样我就可以用不同的方式来设置它的样式,还有一些其他的菜单场景我想添加,但也我曾考虑以某种方式为树视图重用此 html 结构,但从长远来看,树可能会更多地参与其中,但如果可配置,则将图像放在菜单项旁边似乎是一个很好的逻辑改进:)

我之前忘记输入的最后一件事是在控制器的 Menu 操作上使用的菜单选项模型......

公共类 MenuOptions{public bool IsRootMenu { 获取;放;}公共 int ForPageId { 获取;放;}公共 int 深度 { 获取;放;}}

I have created the N'th level Dynamic Menu recursive method which creates a menu.

As seen in above picture the content is returned to ParialView named "_Menu.cshtml" and this Partial View file is empty.

and then there is a _LayoutPage.Cshtml

    <!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    <div>
        <div>
            <input type="text" id="txtSearch" />
            <button id="btnSearch">Search</button>
         </div>
        <div id="Menu">
            @{Html.RenderAction("_Menu", "Home"); }
            @Html.Partial("_Menu")
        </div>
        <div>
            @RenderBody()
        </div>
    </div>
</body>
</html>

it successfully puts the result into the browser but as a plain text as i mentioned above and can be seen below.

How can i make these act like links, not like a plaintext? Help will be appreciated. Thanks :)

解决方案

I took a slightly more involved view on this one.

In the layout I put ...

 @if (Model != null && Model is Core.Objects.Entities.CMS.Page)
 {
                @Html.Action("Menu", new MenuOptions { IsRootMenu = true, ForPageId = Model.Id, Depth = 3 })
 }

I first check if the user is logged in and thus "on a managed page" which only happens if the model is of a specific type "Core.Objects.Entities.CMS.Page".

I then call @Html.Action which calls the following child action on my controller, and I construct my menu options ...

[HttpGet]
[ChildActionOnly]
[Route("~/Menu")]
public ActionResult Menu(MenuOptions options)
{
    //TODO: consider other complex menuing scenarios like a popup / tree based structures
    //      New api calls may be needed to support more complex menuing scenarios

    // TODO: figure out how to build these, perhaps with a string builder
    var expand = string.Empty;
    if (options.Depth > 0)
    {
        switch (options.Depth)
        {
            case 1: expand = "?$expand=PageInfo,Pages($expand=PageInfo)"; break;
            case 2: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo))"; break;
            case 3: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo)))"; break;
            case 4: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=Pages($expand=PageInfo))))"; break;
            case 5: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo)))))"; break;
        }
    }

    var query = options.IsRootMenu
        ? "Core/Page/MainMenuFor(id=" + options.ForPageId + ")" + expand
        : "Core/Page/ChildrenOf(id=" + options.ForPageId + ")" + expand;

    var items = Task.Run(() => Api.GetODataCollection<Page>(query)).Result;

    return PartialView(new MenuViewModel { Origin = options.ForPageId, Pages = items });
}

In my case this area needs a little work and I should probably replace that case statement with some smarter looping code that builds the query.

In short though all this does is pull a hierarchy of Page objects off my OData API to the depth determined by my options passed in as menus tend to vary, some are single level options others go multiple levels but I wanted a reusable menuing system.

Having done that I can take the OData result and build out a model for a menu view which looks like this ...

@model MenuViewModel
@if (Model.Pages != null)
{
    <ul class="menu">
        @foreach (var p in Model.Pages)
        {
            Html.RenderPartial("MenuItem", new MenuItemViewModel { Page = p, Origin = Model.Origin });
        }
    </ul>
}

Menu views setup a list for the root and render a child for each child page, I plan to expand on this view at some point for things like spitting out the parent page which could be in the OData result I pulled in the controller.

And the final piece of the puzzle is the menu item view that deals with rendering each individual menu item ...

@model MenuItemViewModel
<li>
    <a href="@Html.Raw("/" + Model.Page.Path)" @CurrentItem(Model.Page)>@Html.PageInfo(Model.Page).Title</a>
    @if (Model.Page.Pages != null && Model.Page.Pages.Any())
    {
        <ul class="submenu">
        @foreach (var p in Model.Page.Pages)
        {
            Html.RenderPartial("MenuItem", new MenuItemViewModel { Page = p, Origin = Model.Origin });
        }
        </ul>
    }
</li>

@functions{
    MvcHtmlString CurrentItem(Core.Objects.Entities.CMS.Page p)
    {
        if (Model.Origin == p.Id) return new MvcHtmlString("class='selected'");
        return null;
    }
}

Having done all this I end up with essentially a nested set of lists I then use CSS to handle things like popups or dynamic expands ect.

This functionality is not quite complete, I need to make sure I handle "marking the current item" with a class or something so I can style it differently and there are a few other menuing scenarios I would like to add, but also I have considered reusing this html structure in some way for tree views but trees may be a bit more involved in the longer term but doing things like putting an image next to menu items seems like a nice logical improvement if its configurable :)

One last thing I forgot to put in before is the menu options model used on the Menu action in the controller ...

public class MenuOptions
{
    public bool IsRootMenu { get; set; }
    public int ForPageId { get; set; }
    public int Depth { get; set; }
}

这篇关于Mvc 动态菜单填充纯文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆