Función recursiva ASP.NET MVC 3 Razor

76

Bien, entonces quiero mostrar una lista que contiene listas de listas de listas ...

No tengo forma de saber cuántos niveles hay para mostrar, así que pensé que aquí es donde rompo la vieja rutina recursiva.

Sin embargo, estoy teniendo problemas con exactamente cómo hacer esto.

Esto es lo que tengo hasta ahora (a la vista, simplificado):

@foreach(MyObject item in @Model.ListOfObjects){ 
    <div> @item.Title </div>
    //Call recursive function?
}

Ahora cada uno de estos objetos también tiene una List <MyObject>. Quiero mostrar cada nivel debajo de este div, con una sangría de tabulación por nivel, por ejemplo.

Estaba pensando que una función Razor sería lo que debería hacer aquí, pero necesito ayuda para formarla. Aquí está mi pensamiento:

@functions{
    public static void ShowSubItems(MyObject _object){
         if(_object.ListOfObjects.Count>0){
             foreach(MyObject subItem in _object.listOfObjects){

                 // Show subItem in HTML
                 ShowSubItems(subItem);
             }
         }
     }
 }

Pero como puede ver, claramente necesito ayuda :)

Dynde
fuente

Respuestas:

206

El motor de vista de Razor permite escribir ayudantes recursivos en línea con la @helperpalabra clave.

@helper ShowTree(IEnumerable<Foo> foos)
{
    <ul>
        @foreach (var foo in foos)
        {
            <li>
                @foo.Title
                @if (foo.Children.Any())
                {
                    @ShowTree(foo.Children)
                }
            </li>
        }
    </ul>
}
Paolo Moretti
fuente
5
queda una cosa que debe llamar a la vista por @ShowTree (Foos)
vicky
1
Esto funciona muy bien. También puede tener sentido mencionar stackoverflow.com/questions/12943245/… para hacer referencia a variables locales en la página cshtml.
Travis J
¿Cómo se puede implementar este código en asp.net core 2? en asp.net core 2, no hay @helper
dijo Roohullah Allem el
2
@Jahan Parece que los correos electrónicos @helperse han ido en ASP.NET Core. Las funciones en línea son una alternativa potencial: github.com/aspnet/Razor/issues/715#issuecomment-272890766 ¡ pero parecen mucho menos legibles!
Paolo Moretti
@PaoloMoretti Cuando lo defino como Func recursivo, ¿cómo puedo hacerlo? Quiero crear comentarios anidados con Func recursivo. Este error se muestra en VS2018 IDE: "Es posible que el uso de la variable local 'FunctionName' no asignada, la variable local 'FunctionName' no se inicialice antes de acceder"
dijo Roohullah Allem el
13

Creo que es mejor crear un ayudante HTML para esto. Algo como esto:

public static string ShowSubItems(this HtmlHelper helper, MyObject _object)
{
     StringBuilder output = new StringBuilder();
     if(_object.ListOfObjects.Count > 0)
     {
         output.Append("<ul>");

         foreach(MyObject subItem in _object.listOfObjects)
         {
             output.Append("<li>");
             output.Append(_object.Title);
             output.Append(html.ShowSubItems(subItem.listOfObjects);
             output.Append("</li>")
         }
         output.Append("</ul>");
     }
     return output.ToString();
}

Entonces llámalo así:

@foreach(MyObject item in @Model.ListOfObjects){
    <div> @item.Title </div>
    @html.ShowSubItems(item)
}
Edwin de Koning
fuente