如何在 ASP.Net Core 3.1 中动态更新 table 中 headers 第一行的跨度和内容,其中包含 2 行 headers ?

How can I dynamically update the span and the contents of the first row of headers in a table with 2 rows of headers in ASP.Net Core 3.1?

我正在尝试制作一个包含 2 行 headers 的 table,它们都从 2 个单独的数据库 table 动态更新。内容更新部分没问题,可以用。问题是,第一行中的单元格必须跨越第二行中该特定类别的条目数。
我已将第二行类别按元素及其 id 分组,计算 id 并将它们放入 ViewBag。

第一排模特:

    [Table("categories")]
    public class CategoriesModel
    {
        [Column("category_id")]
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Required]
        public int CategoryId { get; set; }

        [Column("category_name")]
        //[Required]
        public string CategoryName { get; set; }
    }

第二排车型:

[Table("materials")]
    public class MaterialModel
    {
        [Column("material_id")]
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Required]
        public int MaterialId { get; set; }

        [Column("height_x_width")]
        [Required]
        public string Dimensions { get; set; }

        [Column("category_id")]
        [Required]
        public int CategoryId { get; set; }

        public List<CategoriesModel> MaterialCategory { get; set; }
    }

视图模型:

public class NationalCampaignViewModel
    {
        public string Campaign { get; set; }

        public IEnumerable<RestaurantModel> Restaurant { get; set; }

        public IEnumerable<CategoriesModel> Categories { get; set; }

        public IEnumerable<MaterialModel> Materials { get; set; }

        public IEnumerable<OptionModel> Options { get; set; }
    }

ViewModelController:

public class NationalCampaignViewModelController : Controller
    {
        private readonly McDdbContext _context;

        public NationalCampaignViewModelController(McDdbContext context)
        {
            _context = context;
        }

        // GET: NationalCampaign
        public async Task<IActionResult> Index(int? id)
        {
            var campaign = await _context.NationalCampaigns.FirstOrDefaultAsync(m => m.Id == id);
            var restaurant = await _context.Restaurants.ToListAsync();
            //var stl = await _context.STL.ToListAsync();
            //var dtl = await _context.DTL.ToListAsync();
            var categories = await _context.CategoriesModel.ToListAsync();
            var options = await _context.OptionModel.ToListAsync();
            var materials = await _context.MaterialModel.ToListAsync();
            var colSpan = materials.OrderBy(x => x.CategoryId).GroupBy(x => x.CategoryId).ToDictionary(g => g.Key, g => g.Count());
            ViewBag.ColSpan = colSpan.Values;

            var tables = new NationalCampaignViewModel
            {
                Campaign = campaign.CampaignName,
                Restaurant = from r in restaurant select r,
                Categories = from c in categories orderby c.CategoryId select c,
                //Options = from o in options select o,
                Materials = from m in materials orderby m.CategoryId select m
            };

            if (id == null)
            {
                return NotFound();
            }


            return View(tables);
        }

视图:

@{
    ViewData["Title"] = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}



<h1>@Model.Campaign</h1>

<div class="container">
    <div class="row">
        <div class="col">
            <table class="table-bordered">

                @foreach (var span in ViewBag.ColSpan)
                {
                    <colgroup>
                        <col span="@span" />
                    </colgroup>
                }
                <thead>
                    <tr align="center">
                        <th>@Html.DisplayNameFor(model => model.Restaurant.FirstOrDefault().Restaurant_Name)</th>

                        @foreach (var c in Model.Categories)
                        {
                            <th scope="colgroup">@c.CategoryName</th>
                        }
                    </tr>
                    <tr>
                        <th>Dimensions</th>
                        @foreach (var m in Model.Materials)
                        {
                            
                            <th>@m.Dimensions</th>
                        }
                    </tr>
                </thead>
                <tbody>
                    @*@foreach (var item in Model.Restaurant)
            {
                <tr>
                    <td>
                        <a asp-controller="Restaurant" asp-action="Edit"
                           asp-route-id="@item.Restaurant_Id">@Html.DisplayFor(modelItem => item.Restaurant_Name)</a>
                    </td>
                </tr>
            }*@
                </tbody>
            </table>
        </div>

要跨越的列数table:

用字典解决了。

控制器:

var colSpan = materials.OrderBy(x => x.CategoryId).GroupBy(x => x.CategoryId).ToDictionary(g => g.Key, g => g.Count());
            Dictionary<string, int> headerValues = new Dictionary<string, int>();

            List<string> keys = new List<string>();

            foreach (var category in categories)
            {
                keys.Add(category.CategoryName);
            }


            headerValues = keys.Zip(colSpan.Values, (k, v) => new { k, v })
              .ToDictionary(x => x.k, x => x.v);

            ViewBag.ColSpan = headerValues;

查看:

@foreach (var item in ViewBag.Colspan)
                        {
                            <th colspan="@item.Value">@item.Key</th>
                        }