9

我在一个强类型的 MVC 4 项目中有一个部分视图。它需要一个数据库表的 IEnumerable 集合。在该表中有 ID、名称和 ParentID,用于存储记录之间的分层连接。调用分部视图的视图也是强类型的,它以整个数据库为模型,将Categories表作为可枚举的集合传递给分部视图:

@Html.Partial("_TreeCategories", @Model.Categories.ToList())

而在局部视图中,我想先取根节点,这样我就可以用递归的方式扩展整棵树。在数据库表中,所有记录都被视为具有 ParentID == null 的根节点。
所以一般来说,我这样做的方式如下:

@model IEnumerable<TreeCollections.OpenAccess.Category>

@if (Model.ToList().Count >= 0)
    {
    @if (Model.ToList()[0].Parent_id == null)
    {
        <text><ul id="navigation"></text>
    }

    @foreach (var node in @Model)
    {
        <li><a href="?@node.Id">@node.Name</a>
            @foreach (var subNode in @Model.Where(s => s.Parent_id == node.Id))
            {
                @Html.Partial("_TreeCategories", subNode)
            }
        </li>
    }
    @if (Model.ToList()[0].Parent_id == null)
    {
        </ul>
    }
}

所以我检查模型的第一个元素的ParentID是否为null,如果是,那么它应该创建一个id为“navigation”的<ul>标签,这样jquery插件就可以识别出它是一个treeview控件. 然后它创建一个带有递归调用的列表标签。递归调用的局部视图将节点的子节点作为模型。最后,如果我们到达局部视图渲染的末尾,并且我们处于“根级别”,它应该编写一个结束 <ul> 标记
然而,也存在一些问题。首先,最后,关闭无序列表标签是错误的,VS 找不到匹配的开始标签。其次,我不知道为什么,但是在顶部,我可以将starter <ul>标签放在标签之间,而我不能在下面的结束标签处这样做。但是我也不确定这些 < ul > 标签,我也觉得那些是错误的。

请帮助我,我已经坚持了好几天了。

4

2 回答 2

17

伙计,你有一些奇怪的事情发生在这里。我感觉到你被卡住的痛苦。

看看这是否能让你的船浮起来。

当您在同一个列表上进行递归时,您需要一个种子值来跟踪您在列表中查找的内容。最好在课堂上做一个父子映射,但是考虑到你的结构,这样做很有趣,应该可以解决问题。

楷模

namespace trash.Models
{
    public class Category
    {
        public int ID { get; set; }
        public int? Parent_ID { get; set; }
        public string Name {get; set;}
    }

    public class SeededCategories
    {
        public int? Seed { get; set; }
        public IList<Category> Categories { get; set; }
    }
}

控制器(注意:您通过将 Seed 属性设置为 null 来启动递归链,这将获取所有 null 父级)

namespace trash.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            IList<trash.Models.Category> categories = new List<trash.Models.Category>();
            categories.Add(new trash.Models.Category { ID = 1, Parent_ID = null, Name = "Top1" });
            categories.Add(new trash.Models.Category { ID = 2, Parent_ID = null, Name = "Top2" });
            categories.Add(new trash.Models.Category { ID = 3, Parent_ID = 1, Name = "Top1Ring1" });
            categories.Add(new trash.Models.Category { ID = 4, Parent_ID = 1, Name = "Top1Ring2" });

            trash.Models.SeededCategories model = new Models.SeededCategories { Seed = null, Categories = categories };
            return View(model);
        }
    }
}

浏览指数

@model trash.Models.SeededCategories

Here's a list
@Html.Partial("_TreeCategories", Model)

部分(您的 _TreeCategories。注意:将种子设置为当前节点 ID 和 volia 递归)

@model trash.Models.SeededCategories

@if (Model.Categories.Where(s => s.Parent_ID == Model.Seed).Any())
{
    <ul>
        @foreach (var node in Model.Categories)
        {
            if (node.Parent_ID == Model.Seed)
            {
                trash.Models.SeededCategories inner = new trash.Models.SeededCategories { Seed = node.ID, Categories = Model.Categories };
            <li><a href="?@node.ID">@node.Name</a>
                @Html.Partial("_TreeCategories", inner)
            </li>
            }
        }
    </ul>
}
于 2013-07-09T17:53:17.827 回答
1

您可以尝试 Shield UI 的递归TreeView for ASP.NET MVC

它允许您使用 RecursiveDataSource 对象指定所有 TreeView 项,该对象可以设置为从远程端点或本地源“懒惰地”检索树项的数据,只要项被扩展。

RecursiveDataSource 是 JavaScript DS 小部件的包装器,它引入了对一些 JS 代码的需求,以及更新将提供数据的服务器代码(实现 Web 服务,或将数据放在视图中的 JS 变量中) )。

于 2016-08-11T11:24:40.970 回答