Métodos auxiliares de navalha de aninhamento

A opção de visualização do Razor chamada helper é algo que está disponível para desenvolvedores desde a ASP.NET MVC3. Os ajudantes funcionam como quaisquer outros métodos expostos ao Razor, mas são compostos de código de visualização e a saída é a HelperResult.

Mas você sabia que pode aninhar ajudantes em Razor? Você pode usar a saída de um auxiliar e passá-la para um auxiliar que contém um HelperResultcomo parâmetro. Aqui está um exemplo rápido:

@helper Container(HelperResult stuff)
{
<div class="stuff-container">
@stuff
</div>
}
@helper Stuff(string s)
{
<p>
Will the real @s,
please stand up
?
</p>
}

Chamar isso em sua visualização do Razor é mais ou menos o que você espera quando os compõe juntos assim:

@Container(Stuff("Slim Shady"))

O código acima produzirá o seguinte HTML, onde o código do segundo auxiliar é colocado dentro do código do auxiliar que o contém:

<div class="stuff-container>
<p>
Will the real Slim Shady,

please stand up?

</p>
</div>

A grande vantagem de usar HelperResulté que é bastante dinâmico, em termos que você pode usar qualquer outro auxiliar:

@* Another helper *@
@helper Sweet(string candy) {
<p>I like @candy</p>
}

@* Invocation with the new helper *@
@Container(Sweet("lollipop"))

<!-- Outputs: -->
<div class="stuff-container>
<p>I like lollipop</p>

</div>

Mas por que?

Aninhar os auxiliares será útil para o contêiner de elementos, onde você precisa trocar as partes que são diferentes dentro desse contêiner. Por exemplo, aqui está um código auxiliar em que o contêiner pode ter a aparência de um “cabeçalho” de outro auxiliar:

@helper ItemsContainer(string containerCssClass, HelperResult headerInfo, List<Item> items) {
<article class="@containerCssClass">
@headerInfo
@foreach(var item in items) {
<dl>
<dt>
@Url.ActionLink(item.Title, ...)
</dt>
<dd>@item.Description</dt>
</dl>
}
</article>
}

O cabeçalho pode ser qualquer coisa, como html-snippet com tag de cabeçalho e um ícone (uso comum de fonte de ícone):

@helper Header(string text, string iconClass = null) {
<h1>
@if (!String.IsNullOrEmpty(iconClass) {
<i class="@iconClass"></i>
}
@text
</h1>
}

O uso seria algo assim, em que o código precisa gerar vários tipos diferentes de itens:

@ItemsContainer(
"news-article",
Header("News", "icon-news"),
Model.NewsItems)

@ItemsContainer(
"blog-article",
Header("The Blog", "icon-blogpost"),
Model.BlogItems)

Usar auxiliares dessa maneira reduzirá alguns dos erros de consistência em seu design HTML que acontecem facilmente quando você corta e cola trechos de código semelhantes.