我正在尝试从分层数据中编写一个基本的HTML无序列表。下面是数据的样子:
public class Task
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Title { get; set; }
public Collection<Task> Tasks = new Collection<Task>( );
}
List<Task> tasks = new List<Task>( );
tasks.Add( new Task { Id = 1, ParentId = null, Title = "Top task" } );
tasks.Add( new Task { Id = 2, ParentId = 1, Title = "Subtask 1" } );
tasks.Add( new Task { Id = 3, ParentId = 2, Title = "Subtask 2" } );
tasks.Add( new Task { Id = 4, ParentId = 1, Title = "Subtask 3" } );
tasks.Add( new Task { Id = 5, ParentId = 4, Title = "Subtask 4" } );
以下是我试图从上面的数据中创建的内容:
<ul>
<li>Top task
<ul>
<li>Subtask 1
<ul>
<li>Subtask 2</li>
</ul>
</li>
</ul>
<ul>
<li>Subtask 3
<ul>
<li>Subtask 4</li>
</ul>
</li>
</ul>
</li>
</ul>
我尝试了以下帖子,并取得了一些成功:
Return unordered list from hierarchical sql data和C# Create HTML unordered list from List using Recursion
这是我从上面的第一个链接改编的代码,它基本上是有效的,但是如果分层数据的顺序发生了变化,该方法就会在第一个不是前一个父项的子项上阻塞。例如,如果我更改数据列表的顺序,如下所示,它将跳过子任务1和2:
tasks.Add( new Task { Id = 2, ParentId = 1, Title = "Subtask 1" } );
tasks.Add( new Task { Id = 1, ParentId = null, Title = "Top task" } );
tasks.Add( new Task { Id = 3, ParentId = 2, Title = "Subtask 2" } );
tasks.Add( new Task { Id = 4, ParentId = 1, Title = "Subtask 3" } );
tasks.Add( new Task { Id = 5, ParentId = 4, Title = "Subtask 4" } );
public class Task
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Title { get; set; }
public Collection<Task> Tasks = new Collection<Task>( );
public Task FindTask( int id )
{
return FindTask( this, id );
}
private Task FindTask( Task task, int id )
{
if( task.Id == id )
{
return task;
}
Task returnTask = null;
foreach( Task child in task.Tasks )
{
returnTask = child.FindTask( id );
if( returnTask != null )
{
break;
}
}
return returnTask;
}
}
List<Task> topTasks = new List<Task>( );
protected void GetHierarchy( int id )
{
List<Task> data = new List<Task>( );
data.Add( new Task { Id = 1, ParentId = null, Title = "Top task" } );
data.Add( new Task { Id = 2, ParentId = 1, Title = "Subtask 1" } );
data.Add( new Task { Id = 3, ParentId = 2, Title = "Subtask 2" } );
data.Add( new Task { Id = 4, ParentId = 1, Title = "Subtask 3" } );
data.Add( new Task { Id = 5, ParentId = 4, Title = "Subtask 4" } );
foreach( var row in data )
{
Task tasks = new Task( );
tasks.Title = row.Title;
tasks.Id = row.Id;
if( row.ParentId == null )
{
topTasks.Add( tasks );
}
else
{
int parentId = row.ParentId.Value;
foreach( Task topTask in topTasks )
{
Task parentTask = topTask.FindTask( parentId );
if( parentTask != null )
{
parentTask.Tasks.Add( tasks );
break;
}
}
}
}
}
protected string Render( )
{
var s = new StringBuilder( );
GetHierarchy( id );
s.Append( "<ul>" );
foreach( Task child in topTasks )
{
RenderTask( s, child );
}
s.Append( "</ul>" );
return s.ToString( );
}
private void RenderTask( StringBuilder s, Task task )
{
s.Append( "<li>" );
s.Append( task.Title );
if( task.Tasks.Count > 0 )
{
s.Append( "<ul>" );
foreach( Task child in task.Tasks )
{
RenderTask( s, child );
}
s.Append( "</ul>" );
}
s.Append( "</li>" );
}
我不想使用jquery treeview或任何其他组件,因为这需要一个独立的解决方案。
有没有人能建议我一个更好的方法,或者至少帮我修复我在上面实现的代码,这样数据的顺序就不会破坏递归?
提前谢谢。
发布于 2020-07-21 14:54:26
最后,我改编了C# Create HTML unordered list from List using Recursion的答案,它工作得很好。下面是我使用的代码:
protected string WriteList( )
{
var s = new StringBuilder( );
List<Task> tasks = new List<Task>( );
tasks.Add( new Task { Id = 2, ParentId = 1, Title = "Subtask 1" } );
tasks.Add( new Task { Id = 1, ParentId = null, Title = "Top task" } );
tasks.Add( new Task { Id = 3, ParentId = 2, Title = "Subtask 2" } );
tasks.Add( new Task { Id = 4, ParentId = 1, Title = "Subtask 3" } );
tasks.Add( new Task { Id = 5, ParentId = 4, Title = "Subtask 4" } );
s.Append( "<ul>" );
foreach( var task in tasks )
{
if( task.ParentId == null )
{
WriteTaskList( tasks, task, s );
}
}
s.Append( "</ul>" );
return s.ToString( );
}
private static void WriteTaskList( List<Task> tasks, Task task, StringBuilder s )
{
s.Append( "<li>" + task.Title );
var subtasks = tasks.Where( p => p.ParentId == task.Id );
if( subtasks.Count( ) > 0 )
{
s.Append( "<ul>" );
foreach( Task p in subtasks )
{
if( tasks.Count( x => x.ParentId == p.Id ) > 0 )
WriteTaskList( tasks, p, s );
else
s.Append( string.Format( "<li>{0}</li>", p.Title ) );
}
s.Append( "</ul>" );
}
s.Append( "</li>" );
}
发布于 2020-07-21 03:55:38
在GetHierarchy函数中,您将按顺序遍历列表中的每个任务。如果列表中的第一个任务的parentId为空,则会将其添加到topTasks列表中。
但是,如果第一个任务有一个非空的parentId,那么它将被添加到topTasks中的父任务中。请注意,此处的父任务在topTasks列表中尚不存在,因此未插入该任务。
我会使用一个递归函数,它首先获取父任务为空的任务,然后使用该任务的id递归调用该函数,直到它到达树的底部。
一个粗略的例子:
Task addSubLists (List<Task> data, Task parent) {
foreach(Task task in data) {
if (task.parentId.Value == parent.Id.Value) {
parent.Tasks.Add(addSubLists(data, task));
}
}
return parent;
}
将顶级任务传递给函数,它会将所有子代添加到中。
https://stackoverflow.com/questions/63005867
复制相似问题