Razor поддерживает лямбда-выражения? - PullRequest
17 голосов
/ 08 февраля 2011

Поддерживаются ли лямбда-выражения / анонимные методы в движке представлений Razor?

Мне трудно выразить в Razor следующее:

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

Примечание: Я знаю, что может решить эту проблему с @foreach, но мне нужно подобное решение для стороннего контроля MVC.Он использует этот механизм для настройки содержимого элемента управления.Он отлично работает для представлений MVC .ASPX, но не может заставить его работать с Razor.

Эквивалент MVC .ASPX (код, который я хотел бы преобразовать в синтаксис Razor):

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

Это для механизма Razor, который поставляется с ASP.NET MVC3.

Ответы [ 3 ]

11 голосов
/ 08 февраля 2011

Вместо вашего <text>@i.DealerName</text> блока вы можете использовать Response.Write(i.DealerName);

Результат такой же, как если бы вы уронили это на страницу Razor - он будет выполняться при рендеринге страницы ... И, честно говоря - я вполне уверен, что это то, во что это будет скомпилировано в любом случае.

Кроме того, так как ForEach() возвращает void, вам придется добавить его на страницу в виде блока кода. Итак, ваш код будет выглядеть примерно так:

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

UPD: Если у вас более серьезное форматирование, вы можете прибегнуть к этому милому маленькому трюку:
(к сожалению, раскраска кода здесь не придаст этому фрагменту никакого значения, но вы определенно поймете, что я имею в виду, если добавите это в visual studio. Примечание: это будет работать только на страницах Razor, а не в файлах кода :))

@{
    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));
        }
    });
}

Надеюсь, что имеет смысл:)

2 голосов
/ 06 марта 2012

Кроме того, вы можете создать лямбда-функцию и вызывать ее для каждого элемента в теле вашего кода Razor (идея пришла от Энди в этом посте ):

@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 голос
/ 17 сентября 2012

Да, они поддерживаются. НО, у Razor есть некоторые странные экранирующие правила, и дополнительные фигурные скобки иногда заставляют его задыхаться, в том числе в расширенных лямбда-выражениях.

Вы можете немного упростить ответ @Artioms, чтобы убрать лишние фигурные скобки с помощью оператора where и (необязательно) предложения

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

становится

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

Может также стать

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

Yay функциональные стили!

...