!1724 refactor(#I44MWD): remove readonly from Items property on Tree component

* feat: 更新逻辑保证示例可用
* wip: refactor Tree component
This commit is contained in:
Argo 2021-08-15 03:34:18 +00:00
parent c861bd5c34
commit b7b2b0b67f
4 changed files with 100 additions and 130 deletions

View File

@ -0,0 +1,60 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/
using BootstrapBlazor.Components;
using System.Collections.Generic;
using System.Linq;
namespace BootstrapBlazor.Shared.Pages.Components
{
class TreeDataFoo
{
public string? Code { get; set; }
public string? ParentCode { get; set; }
public string? Text { get; set; }
public string Icon { get; set; } = "fa fa-fa";
/// <summary>
///
/// </summary>
/// <returns></returns>
public static List<TreeItem> GetTreeItems()
{
var items = new List<TreeDataFoo>();
items.Add(new TreeDataFoo() { Text = "导航一", Code = "1010" });
items.Add(new TreeDataFoo() { Text = "导航二", Code = "1020" });
items.Add(new TreeDataFoo() { Text = "导航三", Code = "1030" });
items.Add(new TreeDataFoo() { Text = "子菜单一", Code = "1040", ParentCode = "1020" });
items.Add(new TreeDataFoo() { Text = "子菜单二", Code = "1050", ParentCode = "1020" });
items.Add(new TreeDataFoo() { Text = "子菜单三", Code = "1060", ParentCode = "1020" });
items.Add(new TreeDataFoo() { Text = "孙菜单一", Code = "1070", ParentCode = "1050" });
items.Add(new TreeDataFoo() { Text = "孙菜单二", Code = "1080", ParentCode = "1050" });
items.Add(new TreeDataFoo() { Text = "孙菜单三", Code = "1090", ParentCode = "1050" });
items.Add(new TreeDataFoo() { Text = "曾孙菜单一", Code = "1100", ParentCode = "1080" });
items.Add(new TreeDataFoo() { Text = "曾孙菜单二", Code = "1110", ParentCode = "1080" });
items.Add(new TreeDataFoo() { Text = "曾孙菜单三", Code = "1120", ParentCode = "1080" });
items.Add(new TreeDataFoo() { Text = "曾曾孙菜单一", Code = "1130", ParentCode = "1100" });
items.Add(new TreeDataFoo() { Text = "曾曾孙菜单二", Code = "1140", ParentCode = "1100" });
items.Add(new TreeDataFoo() { Text = "曾曾孙菜单三", Code = "1150", ParentCode = "1100" });
// 算法获取属性结构数据
return GetSubItems(null, items).ToList();
}
private static List<TreeItem> GetSubItems(string? parentCode, IEnumerable<TreeDataFoo> foos)
{
var subData = foos.Where(i => i.ParentCode == parentCode);
return subData.Select(i => new TreeItem() { Text = i.Text, Items = GetSubItems(i.Code, foos) }).ToList();
}
}
}

View File

@ -29,131 +29,48 @@ namespace BootstrapBlazor.Shared.Pages
private Foo Model => Foo.Generate(Localizer);
private static IEnumerable<TreeItem> GetItems()
private List<TreeItem> Items { get; set; } = TreeDataFoo.GetTreeItems();
private List<TreeItem> CheckedItems { get; set; } = GetCheckedItems();
private static List<TreeItem> GetCheckedItems()
{
var ret = new List<TreeItem>
{
new TreeItem() { Text = "导航一" },
new TreeItem() { Text = "导航二" },
new TreeItem() { Text = "导航三" }
};
ret[0].AddItem(new TreeItem() { Text = "子菜单" });
ret[1].AddItem(new TreeItem() { Text = "子菜单一" });
ret[1].AddItem(new TreeItem() { Text = "子菜单二" });
ret[1].AddItem(new TreeItem() { Text = "子菜单三" });
ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1一" });
ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1二" });
ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2一" });
ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2二" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单一" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单二" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单一" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单二" });
var ret = TreeDataFoo.GetTreeItems();
ret[1].Items[1].Checked = true;
return ret;
}
private IEnumerable<TreeItem> Items { get; set; } = GetItems();
private List<TreeItem> DisabledItems { get; set; } = GetDisabledItems();
private static IEnumerable<TreeItem> GetCheckedItems()
private static List<TreeItem> GetDisabledItems()
{
var ret = new List<TreeItem>
{
new TreeItem() { Text = "导航一" },
new TreeItem() { Text = "导航二", Checked = true, IsExpanded = true },
new TreeItem() { Text = "导航三" }
};
ret[1].AddItem(new TreeItem() { Text = "子菜单一" });
ret[1].AddItem(new TreeItem() { Text = "子菜单二", IsExpanded = true });
ret[1].AddItem(new TreeItem() { Text = "子菜单三" });
ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1一" });
ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1二" });
ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2一" });
ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2二" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单一" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单二" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单一" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单二" });
var ret = TreeDataFoo.GetTreeItems();
ret[1].Items[1].Disabled = true;
return ret;
}
private IEnumerable<TreeItem> CheckedItems { get; set; } = GetCheckedItems();
private static IEnumerable<TreeItem> GetDisabledItems()
private static List<TreeItem> GetIconItems()
{
var ret = new List<TreeItem>
{
new TreeItem() { Text = "导航一" },
new TreeItem() { Text = "导航二", Disabled = true },
new TreeItem() { Text = "导航三" }
};
ret[1].AddItem(new TreeItem() { Text = "子菜单一" });
ret[1].AddItem(new TreeItem() { Text = "子菜单二" });
ret[1].AddItem(new TreeItem() { Text = "子菜单三" });
ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1一" });
ret[1].Items.ElementAt(0).AddItem(new TreeItem() { Text = "孙菜单1二" });
ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2一" });
ret[1].Items.ElementAt(1).AddItem(new TreeItem() { Text = "孙菜单2二" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单一" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾孙菜单二" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单一" });
ret[1].Items.ElementAt(1).Items.ElementAt(1).Items.ElementAt(1).AddItem(new TreeItem() { Text = "曾曾孙菜单二" });
var ret = TreeDataFoo.GetTreeItems();
ret[1].Items[0].Icon = "fa fa-fa";
ret[1].Items[1].Icon = "fa fa-fa";
ret[1].Items[2].Icon = "fa fa-fa";
return ret;
}
private static IEnumerable<TreeItem> GetIconItems()
private static List<TreeItem> GetLazyItems()
{
var ret = new List<TreeItem>
{
new TreeItem() { Text = "导航一", Icon = "fa fa-fa fa-fw" },
new TreeItem() { Text = "导航二", Icon = "fa fa-fa fa-fw" },
new TreeItem() { Text = "导航三", Icon = "fa fa-fa fa-fw" }
};
ret[1].AddItem(new TreeItem() { Text = "子菜单一", Icon = "fa fa-fa fa-fw" });
ret[1].AddItem(new TreeItem() { Text = "子菜单二", Icon = "fa fa-fa fa-fw" });
ret[1].AddItem(new TreeItem() { Text = "子菜单三", Icon = "fa fa-fa fa-fw" });
var ret = TreeDataFoo.GetTreeItems();
ret[1].Items[0].IsExpanded = true;
ret[1].Items[1].Text = "懒加载";
ret[1].Items[1].HasChildNode = true;
ret[1].Items[2].Text = "懒加载延时";
ret[1].Items[2].HasChildNode = true;
ret[1].Items[2].Key = "Delay";
return ret;
}
private static IEnumerable<TreeItem> GetLazyItems()
{
var ret = new List<TreeItem>
{
new TreeItem() { Text = "导航一", IsExpanded = true },
new TreeItem() { Text = "懒加载", HasChildNode = true },
new TreeItem() { Text = "懒加载延时", HasChildNode = true , Key = "Delay" }
};
ret[0].AddItem(new TreeItem() { Text = "子菜单一", Icon = "fa fa-fa fa-fw" });
ret[0].AddItem(new TreeItem() { Text = "子菜单二", Icon = "fa fa-fa fa-fw" });
ret[0].AddItem(new TreeItem() { Text = "子菜单三", Icon = "fa fa-fa fa-fw" });
return ret;
}
private IEnumerable<TreeItem> DisabledItems { get; set; } = GetDisabledItems();
private Task OnTreeItemClick(TreeItem item)
{
Trace?.Log($"TreeItem: {item.Text} clicked");
@ -176,17 +93,19 @@ namespace BootstrapBlazor.Shared.Pages
{
await Task.Delay(800);
}
item.AddItem(new TreeItem() {
item.Items.AddRange(new TreeItem[]
{
new TreeItem()
{
Text = "懒加载子节点1",
HasChildNode = true
},
new TreeItem() { Text = "懒加载子节点2" }
});
item.AddItem(new TreeItem() { Text = "懒加载子节点2" });
item.ShowLoading = false;
}
}
/// <summary>
/// 获得属性方法
/// </summary>

View File

@ -91,7 +91,7 @@ namespace BootstrapBlazor.Components
/// 获得/设置 菜单数据集合
/// </summary>
[Parameter]
public IEnumerable<TreeItem> Items { get; set; } = Array.Empty<TreeItem>();
public List<TreeItem> Items { get; set; } = new List<TreeItem>();
/// <summary>
/// 获得/设置 是否显示 CheckBox 默认 false 不显示

View File

@ -12,12 +12,10 @@ namespace BootstrapBlazor.Components
/// </summary>
public class TreeItem
{
private readonly List<TreeItem> _items = new(20);
/// <summary>
/// 获得 父级节点
/// </summary>
private TreeItem? Parent { get; set; }
public TreeItem? Parent { get; set; }
/// <summary>
/// 获得/设置 是否显示正在加载动画 默认为 false
@ -27,7 +25,7 @@ namespace BootstrapBlazor.Components
/// <summary>
/// 获得/设置 子节点数据源
/// </summary>
public IEnumerable<TreeItem> Items => _items;
public List<TreeItem> Items { get; set; } = new List<TreeItem>();
/// <summary>
/// 获得/设置 TreeItem 标识
@ -76,23 +74,13 @@ namespace BootstrapBlazor.Components
/// </summary>
public bool HasChildNode { get; set; }
/// <summary>
/// 添加 TreeItem 方法 由 TreeItem 方法加载时调用
/// </summary>
/// <param name="item">Menutem 实例</param>
public void AddItem(TreeItem item)
{
item.Parent = this;
_items.Add(item);
}
/// <summary>
/// 获得 所有子项集合
/// </summary>
/// <returns></returns>
public IEnumerable<TreeItem> GetAllSubItems() => Items.Concat(GetSubItems(Items));
private static IEnumerable<TreeItem> GetSubItems(IEnumerable<TreeItem> items) => items.SelectMany(i => i.Items.Any() ? i.Items.Concat(GetSubItems(i.Items)) : i.Items);
private static IEnumerable<TreeItem> GetSubItems(List<TreeItem> items) => items.SelectMany(i => i.Items.Any() ? i.Items.Concat(GetSubItems(i.Items)) : i.Items);
/// <summary>
/// 级联设置复选状态
@ -102,7 +90,10 @@ namespace BootstrapBlazor.Components
foreach (var item in Items)
{
item.Checked = isChecked;
if (item.Items.Any()) item.CascadeSetCheck(isChecked);
if (item.Items.Any())
{
item.CascadeSetCheck(isChecked);
}
}
}