用于ASP.NET MVC TreeView问题的Telerik(Kendo)UI

way*_*mon 6 c# asp.net-mvc treeview telerik kendo-ui

我正在使用MVC 5和最新版本的Telerik(以前的Kendo)UI用于ASP.NET MVC.我正在使用分层数据.我试图在_Layout视图中创建TreeView并使用网址或操作链接填充它.

我目前的代码:

在_Layout视图中:

@Html.Partial("_ProductTree")
Run Code Online (Sandbox Code Playgroud)

"_ProductTree"部分视图:

@(Html.Kendo().TreeView().Name("ProductTree")
    .DataSource(d => d
        .Model(m => m
            .Id("ProductId")
            .HasChildren("Categories"))
    .Read(r => r.Action("_ProductTree", "Home")))
    .DataTextField("ProductName"))
Run Code Online (Sandbox Code Playgroud)

行动方法:

[ActionName("_ProductTree")]
public JsonResult GetProductTree()
{
    var products = _productBusinessService.GetProducts();

    var result = products.Select(p => new
    {
        p.ProductID,
        p.ProductName,
        Categories= c.Categories.Any()
    }).OrderBy(t => t.ProductName);

    return Json(result, JsonRequestBehavior.AllowGet);
}
Run Code Online (Sandbox Code Playgroud)

我有很多问题:

  1. 当我展开具有子节点的父节点时,TreeView将触及action方法并将整个树附加到子节点,而不是仅显示子节点.
  2. 我需要能够将TreeView嵌套两深,例如Product> Category> Type.
  3. 我试图弄清楚如何使用LINQ聚合或投影数据来做一个两层深层次的高层次.
  4. 我尝试关闭LoadOnDemand,但这使得TreeView为Product列表中的每条记录调用一次action方法.

我已经尝试将TreeView Razor代码直接插入到_Layout视图中(不使用局部视图).我意识到我可能需要将action方法移动到基本控制器类中并在每个控制器中继承它以阻止它将列表附加到父节点.如果我不能尽快使用它,我可能不得不使用Kendo UI Professional或开源替代品.

你们当中有些人可能会想说这个问题已在其他地方得到解答. 我找到的帖子都没有解决使用Telerik TreeView填充和显示嵌套(多个深层)分层数据的问题.

有这篇文章

嵌套的DataSources和带有kendo ui的TreeView

但它适用于TreeView的JavaScript版本(不是MVC的UI)版本,并且尚未得到解答.

预先感谢您的帮助!

way*_*mon 4

代码中的解决方案:

_Layout 视图:

@Html.Partial("_ProductTree")
Run Code Online (Sandbox Code Playgroud)

或者

@RenderSection("productTree", false)
Run Code Online (Sandbox Code Playgroud)

然后在内容视图中

@section productTree
{
    @Html.Partial("_ProductTree")
}
Run Code Online (Sandbox Code Playgroud)

_ProductTree 部分视图

@(Html.Kendo().TreeView().Name("ProductTree")
    .DataSource(d => d
        .Model(m => m
            .Id("Id")
            .HasChildren("HasChildren")
            .Children("Children"))
    .Read(r => r.Action("_ProductTree", "Home")))
    .DataTextField("Name"))
Run Code Online (Sandbox Code Playgroud)

我将操作方法​​移至 BaseController 抽象类,任何需要显示 ProductTree TreeView 的控制器都可以继承该抽象类。数据是从 ProductService 和 CategoryService 中提取的,并使用 LINQ 投影聚合到匿名对象中:

    [ActionName("_ProductTree")]
    public JsonResult GetProductData()
    {
        var products = _productBusinessService.GetProducts();

        foreach (var product in product)
        {
            foreach (var category in product.Categories)
            {
                category.ProductTypes =
                    _productService.GetProductTypes(category.CategoryId);                                           
            }
        }

        var productTreeData = products.Select(p => new
        {
            Id = p.ProductId,
            Name = p.ProductName,
            HasChildren = p.Categories.Any(),
            Children = p.Categories.Select(c => new
            {
                Id = c.CategoryId,
                Name = c.CategoryName,
                HasChildren = c.ProductTypes.Any(),
                Children = c.ProductTypes.Select(t => new
                {
                    Id = t.ProductTypeId,
                    Name = t.ProductTypeName,
                    HasChildren = false
                }).OrderBy(t => t.Name).ToList()
            }).OrderBy(c => c.Name).ToList()
        }).OrderBy(p => p.Name).ToList();

        return Json(productTreeData, JsonRequestBehavior.AllowGet);
    }
Run Code Online (Sandbox Code Playgroud)

结果是一个 3 层深度、完全填充、排序的用于 ASP.NET Treeview 的 Telerik UI,其中包含 Product >> Category >> ProductType 的名称和 ID。在这种情况下,打开或关闭 LoadOnDemand 似乎没有什么区别。在 TreeView 中使用 Bind 应该会有所不同。