Aaron Anodide
Aaron Anodide

Reputation: 17186

Iterating over tree nodes in MVC razor view?

Is there any way to code walking the nodes of an a cyclic directed graph?

I'm a little new to ASP.NET MVC and the mode I'm in is trying to render the data in the view model using a contained snippet of logic.

That is to say, if there's no non recursive way to do this then what's the best way to do it recursively "MVC style"?

Here's what I've got so far.

Model:

namespace AaronWeb.Models
{
    public class Node
    {
        public Node()
        {
            Nodes = new List<Node>();
            Data = string.Empty;
        }

        public ICollection<Node> Nodes { get; set; }

        public string Data { get; set; }

        public override string ToString()
        {
            if (Data != null)
            {
                return Data.ToString();
            }
            else
            {
                return string.Empty;
            }
        }
    }
}

View

@model AaronWeb.Models.Node

@{
    var q = new Queue<AaronWeb.Models.Node>();
    q.Enqueue(Model);
}
<h1>Graph Partial View</h1>

@while (q.Count > 0)
{
    var node = q.Dequeue();
    <ul>
        <li>@node.ToString()
            @if (node.Nodes.Count > 0)
            {
                <ul>
                    @foreach (var child in node.Nodes)
                    {
                        <li>
                            @child.ToString()
                        </li>
                        q.Enqueue(child);
                    }
                </ul>
            }
        </li>
    </ul>
}

Action Method

public ActionResult Graph()
{
    var model = new Node
    {
        Data = "Foo",
        Nodes = new[] {
             new Node
             {
                 Data = "Bar",
                 Nodes = new [] {
                     new Node
                     {
                         Data = "Bing"
                     },
                     new Node
                     {
                         Data = "Bang"
                     }
                 }
             },
             new Node
             {
                 Data = "Bat"
             },
         },
    };
    return View(model);
}

Result (Wrong)

enter image description here

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Graph</title>
</head>
<body>
    <div>

<h1>Graph Partial View</h1>

    <ul>
        <li>Foo
                <ul>
                        <li>
                            Bar
                        </li>
                        <li>
                            Bat
                        </li>
                </ul>
        </li>
    </ul>
    <ul>
        <li>Bar
                <ul>
                        <li>
                            Bing
                        </li>
                        <li>
                            Bang
                        </li>
                </ul>
        </li>
    </ul>
    <ul>
        <li>Bat
        </li>
    </ul>
    <ul>
        <li>Bing
        </li>
    </ul>
    <ul>
        <li>Bang
        </li>
    </ul>

    </div>
</body>
</html>

Upvotes: 3

Views: 2309

Answers (1)

Aaron Anodide
Aaron Anodide

Reputation: 17186

I figured this out myself.

The key was to realize I could call a partial view recursively!

@model AaronWeb.Models.Node
<ul>
    <li>@Model.ToString()
        @foreach (var child in Model.Nodes)
        {
            Html.RenderPartial("_GraphPartial", child);
        }
    </li>
</ul>

Upvotes: 10

Related Questions