Razor - как преобразовать содержимое в переменную
Как отобразить часть 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))
Я просто не могу понять, как писать без параметров lambdas (Func<object>
). параметр int
в обоих lambdas выше - это фиктивный. Кажется, что Razor требует один параметр (и уже создает переменную "item", чтобы обозначить ее внутри выражения).
Ответы
Ответ 1
В принципе, OP уже ответила на проблему, потому что вы могли бы сделать что-то вроде:
@{
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
}
Ответ 2
Возможно, вы можете использовать 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")
Ответ 3
На всякий случай, если кто-то еще найдет этот пост (как и я), Энди Обновление почти там. В дополнение к приведенному примеру все, что вам нужно сделать для доступа к '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), это работает.
Ответ 4
Если у вас есть вид IHtmlContentBuilder в представлении Razor, вы можете использовать эти расширения.
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>