【问题标题】:asp.net core pass Model to Layoutasp.net core 将模型传递给布局
【发布时间】:2021-09-30 04:36:36
【问题描述】:

我有一个布局页面,其结构在其中使用导航栏和@RenderBody()

后来我做了一个方法来生成页面和导航栏本身。因此,导航栏不再固定。

然后我制作了一个局部视图来循环浏览导航栏项目并将它们显示在布局中的相同位置。但我不知道如何在布局中导入模型。

我想知道有没有可以触发动作的标签助手?返回所需的模型

我的布局是这样的

<html lang="en">
<head>
     ...
</head>
<body>

    <header>
         <partial name="_NavBar" model="????" />
    </header>

    <main class="mb-3">
        <div class="container-fluid">
            @RenderBody()
        </div>
    </main>

    <footer id="footer" class="border-1 border-top border-primary">
        <div class="container-fluid py-4">
            <div class="copyright">
                &copy; Copyright 
            </div>
        </div>
    </footer>

    @RenderSection("Scripts", required: false)

</body>
</html>

有什么想法可以显示这个导航部分吗?或者也许使用另一个标签助手?或任何可能的解决方案?

【问题讨论】:

  • 您可以创建一个服务来提供您需要的数据并在您的部分中使用@inject。 BR
  • @RoarS。那个怎么样?你的意思是像 ViewModel 这样的东西吗?
  • 这听起来像是使用 ajax 从服务器获取数据并使用 $('#id').append(html_content) 生成带有数据的自定义视图并在浏览器中显示。
  • 查看View Components。它们实际上等效于在页面上执行一个孤立的操作,并且可以用作标签助手。

标签: html asp.net-mvc asp.net-core


【解决方案1】:

我同意@Roars,请允许我在这里展示一些示例代码。

首先,让我们创建一个可以收集目标数据以显示导航的服务,例如导航栏中包含的菜单存储在数据库中,我们需要先查询出来。我改用模拟数据:

using System.Collections.Generic;
using WebApplication1.Models;

namespace WebApplication1.Services
{
    public class ChildService : IChildService
    {
        public List<Menu> GetNav() {
            return new List<Menu> {
                new Menu{ MenuId = 1, MenuName = "name1" },
                new Menu{ MenuId = 2, MenuName = "name2" }
            };
        }
    }
}

界面:

using System.Collections.Generic;
using WebApplication1.Models;

namespace WebApplication1.Services
{
    public interface IChildService
    {
        public List<Menu> GetNav();
    }
}

菜单实体:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebApplication1.Models
{
    public class Menu
    {
        public int MenuId { get; set; }
        public string MenuName { get; set; }
    }
}

Startup.cs -> ConfigureSerivces 配置注入:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddSingleton<IChildService, ChildService>();
        }

在startup.cs中设置好依赖后,我们就可以在views中使用DI了。我创建了一个 Razor 视图和inject my query result

@using WebApplication1.Services
@inject IChildService childService 
@{
    var menus = childService.GetNav();
}

<h2>hello world</h2>
<div>
    @foreach (var item in menus)
    {
        <div>@item.MenuName</div>
    }
</div>

最后,使用部分标签将这个视图嵌入到其他视图中。

@page
@model WebApplication1.Pages.Childs.IndexModel
@{
}

<h2>index for child</h2>

<a href="/Childs/Edit?id=1">Edit</a>

<partial name="~/Pages/Childs/test.cshtml" />

这是测试结果:

【讨论】:

    【解决方案2】:

    非常感谢你们,@Tiny Wang @Roar S. 和 @Cake or Death
    我通过添加名为ViewComponent 的东西找到了很好的解决方案。而且我觉得还是跟大家分享一下比较好。

    它有助于在其类中包含您需要的任何逻辑,并允许在其视图中包含模型。

    这里有 3 个步骤 - 但首先是模型

    public class Page
    {
        [Key]
        public Guid Id { get; set; }
        public int PageOrder { get; set; } = 0;
    
        public string pageName { get; set; }
        public string pageDescreption { get; set; }
        public string pageHtmlContent { get; set; }
    
        public string NavIcon { get; set; } // svg icon  
        public bool IsNavBarItem { get; set; }
    }
    

    (1) ViewComponent架构:

    (2) ViewComponent 类:

    public class NavBarViewComponent : ViewComponent
    {
        private readonly ApplicationDbContext context;
    
        public NavBarViewComponent(ApplicationDbContext _context)
        {
            context = _context;
        }
    
        // https://www.youtube.com/watch?v=exokw7WQQ-A
        public IViewComponentResult Invoke()
        {
            // this is how to avoid error of can't convert IQueryable to IEnumerable
            IEnumerable<Page> pages = context.pages.Where(P => P.IsNavBarItem == true).AsEnumerable<Page>();
            return View(pages);
        }
    }
    

    (3) ViewComponent 查看:

    @model IEnumerable<Page>
    ... whatever
    <ul class="navbar-nav">
        @foreach (var item in Model)
        {
            <li class="nav-item">
                <a asp-action="PageView" asp-controller="Home" asp-route-PageID="@item.Id" class="nav-link">
                    @Html.Raw(@item.NavIcon)
                    @item.pageName
                </a>
            </li>
        }
    </ul>
    ... whatever
    

    最后要在任何地方显示这个导航,只需要在布局中包含组件

    @await Component.InvokeAsync("NavBar")
    

    【讨论】:

      猜你喜欢
      • 2011-05-08
      • 2022-10-01
      • 2019-03-09
      • 1970-01-01
      • 2020-10-24
      • 1970-01-01
      • 1970-01-01
      • 2017-08-25
      • 1970-01-01
      相关资源
      最近更新 更多