Razor - как отобразить содержимое в переменную - PullRequest
14 голосов
/ 28 ноября 2010

Как отрисовать кусок Html в переменную в Razor? В Spark я писал следующий код:

<content var="t">
    <a class="tab" href="">Tab name</a>
</content>

<content var="tc">
    <div class="tabcontent">
        <p>Here goes tab content</p>
    </div>
</content>

!{tabs(t, tc)}

две переменные передаются макросу, который делает все удобное для переноса содержимого на вкладку.

Какой лучший способ сделать то же самое в Razor?

Обновление: Мне кажется, я понял ..

В Razor конструкция @<text>...</text> может использоваться пользователем для создания лямбда-выражений, которые можно использовать позже, что является расширенным эквивалентом присвоения части HTML переменной. Приведенный выше пример может быть реализован следующим образом:

Func<int, object> t =
    @<text>
        <a class="tab" href="">Tab name</a>
    </text>;

Func<int, object> tc =
    @<text>
        <div class="tabcontent">
            <p>Here goes tab content</p>
        </div>
    </text>;


@tabs(t(0), tc(0))

Я просто не могу понять, как писать лямбды без параметров (Func<object>). параметр int в обеих лямбдах выше является фиктивным. Кажется, что Razor требуется один параметр (и он уже создает переменную «item» для обозначения его в выражении).

Ответы [ 4 ]

7 голосов
/ 21 июня 2013

По сути, ОП уже ответил на проблему: вы можете сделать что-то вроде:

@{
   Func<dynamic, object> a = @<text>
       Some Text        
   </text>;
   @a(new object())
}    

Если текст предназначен только для одной строки, вы даже можете использовать оператор "@:", просто remmebr дляиметь точку с запятой (или, если ей нужны закрывающие скобки или скобки) на следующей строке, как в следующем примере:

@{
   Func<dynamic, object> a = @: Some Text
   ;    
   @a(new object())
}

Однако вы можете захватить его непосредственно в виде строки, если хотите

@{
    string a = ((Func<dynamic, object>)(@<text>
                    Some Text
                </text>))("").ToString();
    @a //Output directly as a string        
}

Вы можете даже заключить его в функцию:

@functions{
     public string ToString(Func<dynamic, object> input)
     {
          return input("").ToString();
     }
}

@{
    string a = ToString(@<text>
                    Some Text
               </text>);
    @a //Output directly as a string        
 }
6 голосов
/ 06 марта 2012

На тот случай, если кто-нибудь еще найдет этот пост (как я), обновление Энди почти там.В дополнение к приведенному примеру все, что вам нужно сделать для доступа к int в приведенном примере, это ссылка @item.В блоках @<text></text> переменная item содержит модель, к которой она была вызвана.

Вот пример того, как ее можно использовать:

@model PageData

@{
    Func<Customer, object> sayHi = 
        @<text>
             <li>Hello @(item.FirstName)!</li>
         </text>;
}

<ul>
    @foreach(var customer in Model.Customers)
    {
        sayHi(customer);
    }
</ul>

В большинстве случаев вам, вероятно, следуетиспользуйте частичное представление вместо функции, подобной этой.Но в редких случаях, когда частичное представление невозможно (например, при использовании библиотеки RazorEngine), это работает.

5 голосов
/ 28 ноября 2010

Возможно, вы можете использовать HtmlString?Я не думаю, что мне это очень нравится, но вот что я бы попробовал как точный перевод того, что у вас есть ...

@{
    var t = new HtmlString("<a class='tab' href=''>Tab name</a>");
    var tc = new HtmlString("<div class='tabcontent'><p>Here goes tab content</p></div>");
}
@tabs(t, tc)

Итак ... Я не знаю, какой у вас макрос SparkПохоже, но это похоже на возможность использовать помощника в Razor.У вас может быть что-то вроде:

@helper Tabs(string tabName, string tabContent)
{
    <!-- some wrapper code -->   
    <a class="tab" href="">@(tabName)</a>
    <!-- some more wrapper code -->
    <div class="tabcontent">
        <p>@(tabContent)</p>
    </div>
    <!-- still more wrapper code -->
}

Затем вы называете это со своей страницы следующим образом:

@Tabs("Tab Name", "Here goes tab content")
0 голосов
/ 30 сентября 2017

Если у вас в представлении Razor IHtmlContentBuilder, вы можете использовать эти расширения.

    public static IHtmlContentBuilder AppendRazor(this IHtmlContentBuilder htmlContentBuilder, Func<IHtmlContent, dynamic> lamda)
    {
        var html = lamda(null);
        return htmlContentBuilder.AppendHtml(html);
    }

    public static IHtmlContentBuilder AppendRazor<T>(this IHtmlContentBuilder htmlContentBuilder, Func<T, IHtmlContent> lamda, T model)
    {
        var html = lamda(model);
        return htmlContentBuilder.AppendHtml(html);
    }

Использование

@{
    HtmlContentBuilder contentBuilder = new HtmlContentBuilder();
    contentBuilder.AppendRazor(@<text><p>Hello @Model.Name<p></text>);
    contentBuilder.AppendRazor(@<text><p>Hello @item.CustomerName<p></text>, customer);
}
<div>
     @contentBuilder
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...