在 Blazor 中构建文件夹树






4.75/5 (7投票s)
前端和后端文件夹树的实现
引言
由于 Blazor 是一种相对较新的技术,可能很难找到其他框架中常见的特性。这就是递归文件夹树的情况,我只能找到“将我的包添加到你的项目”的解决方案。本文的目的是分享该解决方案的前端和后端,以及构建文件夹树所需的全部代码。
从后端开始
首先,我使用了一个名为“Group
”的类,它将是“Folder
”(如果你愿意,可以将其命名为“Folder
”)。这是一个简单且常见的类。唯一值得注意的区别是,它有一个“ParentGroupId
”整数属性,用于引用自身(是的,一个组中包含一个组!),这对于创建我们需要的“文件夹中包含文件夹”效果非常重要。
public class Group
{
public string Name { get; set; }
public string? Description { get; set; }
public int? ParentGroupId { get; set; }
public Group ParentGroup { get; set; }
public virtual List<Group> SubGroups { get; set; }
}
你可以将其存储在 SQL Server、MySQL 或任何其他数据库中。我不会介绍如何使用 SQL Server 或创建表。我假设你已经可以将该类保存到表中并检索信息。
递归方法以获取所有文件夹/组信息
在你的存储库/控制器/或其他你正在使用的组件中,你需要创建一个方法来递归地获取所有组/文件夹信息。在我的例子中,我使用了我公司的一个名为 Sparc 的框架,它完成了所有这些神奇的操作。最后,我会发布一个链接,你可以在那里获取更多信息。这个方法将无限地包含组中的组(无论有多少组)。你可以在下面找到代码。
public async Task<List<Group> GetGroups()
{
// Get all groups from DB to save all the extra database calls
var allGroups = await GroupRepository
.Query
.ToListAsync();
// Start recursive function with the top of the tree
LoadSubgroups(allGroups, null);
allGroups = allGroups.Where(x => x.ParentGroupId == null).ToList();
return allGroups;
}
private List<Group> LoadSubgroups(List<Group> allGroups, Group? parentGroup)
{
var groups = allGroups.Where(x => x.ParentGroupId == parentGroup?.Id).ToList();
foreach (var group in groups)
group.SubGroups = LoadSubgroups(allGroups, group);
return groups;
}
你可以注意到,GetGroups()
方法调用了 LoadSubgroups()
方法,而 LoadSubgroups()
方法又调用了自身!其思想是 LoadSubgroups()
方法递归地调用自身,直到没有组需要加载为止。
使用组件处理前端
我们将面临与后端相同的挑战:递归性!在这种情况下,我们需要使用 Blazor 组件来创建递归效果,为每个将要显示的新组/文件夹创建新的 HTML 元素。我假设你已经可以从 API 获取组/文件夹信息。
GroupTree 组件
首先,我们需要创建 GroupTree
/FolderTree
组件
<div class="folder-tree-wrapper">
<ul class="folder-tree">
@foreach (var group in Groups)
{
<GroupItem Group="group" />
}
</ul>
</div>
@code {
[Parameter] public List<GetGroupsResponse> Groups { get; set; }
}
你可以注意到,有一个未定义的 HTML 元素:<GroupItem />
元素!这将是另一个组件(子组件),它将实际包含组。
GroupItem 组件
<li>
<div class="item-container">
@if (Group.SubGroups.Any())
{
@if (Group.IsExpanded)
{
<i class="material-icons expand-more"
style="transform: rotate(180deg)"
@onclick="ToggleGroup">expand_less</i>
}
else
{
<i class="material-icons expand-more"
style="transform: rotate(90deg)"
@onclick="ToggleGroup">expand_less</i>
}
}
<i class="material-icons" style="cursor: pointer;
@(Group.SubGroups.Any() ? "" : "padding-left: 18px")">
@(allEntriesSelected ? "check_box" : "check_box_outline_blank")</i>
<div style="display: inline-block" @onclick="ToggleGroup">
<i class="material-icons">folder</i>
<div style="display: inline-block">@Group.Name</div>
</div>
</div>
@if (Group.SubGroups.Any() && Group.IsExpanded)
{
<ul>
@foreach (var subGroup in Group.SubGroups)
{
<GroupItem Group="subGroup"/>
}
</ul>
}
</li>
@code {
[Parameter] public GetGroupsResponse Group { get; set; }
public bool allEntriesSelected { get; set; }
async Task ToggleGroup()
{
Group.IsExpanded = !Group.IsExpanded;
}
}
就这样!这就是使用 Blazor 创建文件夹/树解决方案所需的一切。现在你只需要在想要使用它的页面上调用 GroupTree
组件,如下所示
<GroupTree Groups="groups" />
如果你有任何问题或想了解更多关于我提到的 Sparc 解决方案的信息,请给我留言!无论如何,我都可以帮助你。:)
历史
- 2022 年 2 月 10 日:初始版本