首页 > 解决方案 > 特定页面上的左侧导航栏利用每个页面的 MVC 模型数据

问题描述

我已使用此处找到的左侧导航栏的代码。但是,我只需要它出现在特定页面上。当它存在时,我需要将数据从 View 模型传递到导航栏中的链接,以便成功导航到所选的正确页面。

除了在每一页上复制粘贴代码之外,还有其他最佳做法吗?似乎我可以将导航栏放在 _Layout.cshtml 上,让它出现在指定的页面上,然后使用 MVC 或 jQuery 将数据传递给链接。

标签: asp.net-coremodel-view-controller

解决方案


您可以查看 ASP.NET Core视图组件。在您的_Layout.cshtml中,您添加一些逻辑来确定是否要显示组件,然后使用适当的参数呈现它。

这是一个示例,其中链接是根据从控制器传递的名称选择的,但您可以添加所需的任何逻辑,包括从数据库中获取它们。

家庭控制器.cs

public class HomeController : Controller
{
    public IActionResult Index()
    {
        // data to be passed to the component; 
       // will also be used to determine if the navbar should be displayed
        ViewData["NavMenuPage"] = "Index";
        return View();
    }
}

_Layout.cshtml

// condition to render the navigation menu 
@if (ViewData["NavMenuPage"] != null)
{
    // ASP.NET Core will search for a component named NavMenu, 
    // and invoke it with the provided data (here, the NavMenuPage set in the controller)
    @await Component.InvokeAsync("NavMenu", ViewData["NavMenuPage"])
}

NavMenuViewComponent.cs

这里,NavMenu是你的组件的名称,并且类名必须加上后缀ViewComponent才能被 ASP.NET Core 找到。该类可以放在项目中的任何位置。

public class NavMenuViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync(string pageName)
    {
        var links = GetLinksForPage(pageName);
        return View(links);
    }

    private Dictionary<string, string> GetLinksForPage(string pageName)
    {
        Dictionary<string, string> links = null;
        switch (pageName)
        {
            case "Index":
                links = new Dictionary<string, string> {
                    { "Link 1", "https://www.google.com" },
                    { "Link 2", "https://www.example.com" },
                };

                break;

            case "Privacy":
                links = new Dictionary<string, string> {
                    { "Link 3", "https://www.stackoverflow.com" },
                };

                break;
        }


        return links;
    }
}

/Views/Shared/Components/NavMenu/Default.cshtml

这是将呈现您的链接的代码。请注意,此文件不能放在任何地方:它必须遵循某些命名约定,如文档中所述。在这里,我把它放在共享文件夹中。

// type of the object passed to View() call in NavMenuComponent.InvokeAsync
@model Dictionary<string, string>

<nav>
    @foreach (var link in Model)
    {
        <div><a href="@link.Value">@link.Key</a></div>
    }
</nav>

推荐阅读