2011-02-08 25 views
17

¿Se soportan las expresiones lambda/métodos anónimos en el motor Razor view?¿Las expresiones lambda son compatibles con Razor?

Estoy teniendo dificultades para expresar lo siguiente en la maquinilla de afeitar:

@Model.ToList().ForEach(i => 
    { 
     if (i.DealerName != null) 
     { 
      <text> 
       @i.DealerName 
      </text> 
     } 
    } 

Nota: Sé que puede resolver esto con @foreach pero necesito una solución similar para un control MVC tercera parte. Está usando este mecanismo para establecer el contenido del control. Funciona bien para las vistas MVC .ASPX, pero no puede funcionar con Razor.


equivalente MVC .ASPX (el código me gustaría convertir a la sintaxis Razor):

<% Model.ToList().ForEach(i => 
     { 
      if (i.DealerName != null) 
      { 
      %> <%=i.DealerName%> <% 
      }; 
     }); 
%> 

Esto es para el motor de la maquinilla de afeitar que se incluye con ASP.NET MVC3.

Respuesta

11

lugar de su bloque <text>@i.DealerName</text> se puede utilizar un Response.Write(i.DealerName);

El resultado es el mismo, como si se le cae esto en una página Razor - se ejecutará mientras se renderiza la página .. Y francamente - Estoy bastante seguro esto es en lo que se compilará de todos modos.

Además, dado que ForEach() devuelve nulo, debe dejarlo en la página como un bloque de código. Así que su código sería algo como esto:

@{ 
    Model.ToList().ForEach(i => 
    { 
     if (i.DealerName != null) 
     { 
      Response.Write(i.DealerName); 
     } 
    }); 
} 

UPD: Si tiene el formato más grave, se puede recurrir a este pequeño truco:
(por desgracia, el coloreado de código aquí no dar este fragmento cualquier crédito, pero que sin duda va a ver lo que quiero decir si se le cae esto en visual Studio Nota:. esto sólo funcionará en las páginas de la maquinilla de afeitar, no los archivos de código :))

@{ 
    Model.ToList().ForEach(i => 
    { 
     if (i.DealerName != null) 
     { 
      Response.Write(((Func<dynamic, object>)(
       @<text> 
        <b>Hello Dealer named: @item.DealerName 
        Multiline support is <em>Beautiful!</em> 
       </text>)).Invoke(i)); 
     } 
    }); 
} 

esperanza que tiene sentido :)

+0

Sí 'Respuesta.Write' funciona, pero para un ejemplo más complejo, la concatenación de cadenas se sale de control muy rápidamente. :( –

+0

Sí, tienes razón ... He actualizado la publicación para permitir prácticamente cualquier tipo de código Razor dentro de esta función. Disfruta :) –

+0

Gracias por tu molestia, tomaste Artiom. Me gusta particularmente tu truco de múltiples líneas. Desafortunadamente no puedo entrar en un bloque de código como este. Como mencioné en mi pregunta, necesito proporcionar mi contenido/plantilla dentro de la expresión lambda de los proveedores de componentes para construir el control. Parece tan simple en el código .ASPX. ¿Debo entender que las expresiones lambda no son compatibles con Razor al mismo nivel que con el código MVC .ASPX? –

2

Como alternativa, puede crear una función lambda, y llamar a que para cada elemento en el cuerpo de su código Razor (la idea surgió de Andy en this post):

@model IEnumerable<Dealer> 

@{ 
    Func<Dealer, object> sayHi = 
     @<text> 
      <b>Hello Dealer named: @(item.DealerName)</b> 
      Multiline support is <em>Beautiful!</em> 
     </text>; 
} 

<div> 
    @foreach(var dealer in Model.ToList()) 
    { 
     sayHi(dealer); 
    } 
</div> 
1

Sí, ellos son compatibles. PERO, Razor tiene algunas reglas de escape extrañas y llaves adicionales harán que se ahogue a veces, incluso aquellas en expresiones lambda extendidas.

Puede simplificar los @Artioms contestar un poco para eliminar esos apoyos adicionales con un dónde y opcionalmente una cláusula select

@{ 
    Model.ToList().ForEach(i => 
    { 
     if (i.DealerName != null) 
     { 
      Response.Write(i.DealerName); 
     } 
    }); 
} 

convierte

@{ 
    Model.Where(i=>i.DealerName != null).ToList().ForEach(i => 
    { 
      Response.Write(i.DealerName); 
    }); 
} 

también podría convertirse

@{Model.Where(i=>i.DealerName != null).Select(i=>i.DealerName) 
    .ToList().ForEach(Response.Write);} 

¡Estilos funcionales de Yay!

+0

Gracias por los comentarios, pero no responde la pregunta. –

+0

He reformulado la parte superior para que sea un poco más clara: mejora la respuesta de @Artioms. También proporcioné otra solución alternativa: eliminar llaves adicionales que podrían confundir al compilador de afeitar. Creo que es útil, al mínimo. – scaryman

Cuestiones relacionadas