tutorial net mvc español asp c# asp.net asp.net-mvc-3 .net-4.0 razor

c# - net - mvc 4



ASP.Net MVC3-Pase el marcado de la maquinilla de afeitar como parámetro (3)

Este es un ejemplo que utilizo para representar el marcado de la plantilla de jQuery al pasar un Id. De plantilla y una sintaxis de estilo de afeitar para la propia plantilla:

public static MvcHtmlString jQueryTmpl(this HtmlHelper htmlHelper, string templateId, Func<object, HelperResult> template) { return MvcHtmlString.Create("<script id=/"" + templateId + "/" type=/"x-jquery-tmpl/">" + template.Invoke(null) + "</script>"); }

y esto se llamaria con

@Html.jQueryTmpl("templateId", @<text>any type of valid razor syntax here</text>)

Básicamente, solo use Func<object, HelperResult> como su parámetro y template.Invoke(null) Func<object, HelperResult> template.Invoke(null) (con argumentos si es necesario) para representarlo. Obviamente, puede omitir la llamada a .Invoke() para evitar el procesamiento del marcado "predeterminado".

Tengo un ayudante llamado EditableArea que proporciona a un usuario un div editable en tiempo de ejecución (a través de JS). El ayudante EditableArea comprueba si existe un área editable (no relacionada con el Area de MVC) con el ID especificado en la base de datos, si es así, representa el HTML del área; de lo contrario, muestra el marcado predeterminado especificado como un parámetro para el ayudante:

@Html.EditableArea(someId, "<p>Click to edit contents</p>")

Todo funciona bien, pero me gustaría cambiarlo para que el marcado predeterminado se especifique no como una cadena sino en una sintaxis de afeitar, algo como:

@using (Html.EditableArea(someId)) { <p>Click to edit contents</p> }

O algo similar, como la forma en que funciona @section en MVC3.

¿Cómo puedo lograr eso?

Puedo hacer una IDisposable que en su Dispose cierra el TagBuilder, etc., pero no puedo evitar representar el margen interno de Razor incluso si el ayudante encuentra un área con una ID (puedo borrar el contenido renderizado en Dispose () pero el código está dentro el {} todavía se ejecutaría, que me gustaría omitir).

Y si no uso el using ¿hay alguna otra forma de pasarle un bloque de afeitar al ayudante, que puede ser o no realmente prestado por el ayudante?


Llevando esto más lejos, es posible pasar el marcado directamente a un ayudante, sin un método de extensión.

@helper HelperWithChild(Func<object, HelperResult> renderChild) { <div class="wrapper"> @renderChild(this) </div> } @HelperWithChild(@<h1>Hello</h1>)

Para el marcado multilínea, también se requiere <text> :

@HelperWithChild(@<text> @AnotherHelper() <h1> With more markup </h1> </text>) @helper AnotherHelper() { <p> Another helper </p> }

Aunque no estoy seguro de cómo funcionará this con Model , mis ayudantes solo usan sus parámetros.


Solo para ampliar la respuesta aceptada, ya que me tomó bastante tiempo resolver un problema similar y esta es la pregunta que surgió. Lo que realmente necesitaba era un @helper , que aceptaría texto de afeitar, ya que la plantilla debería contener bastante código. @helper item(Func<object, HelperResult> input) durante un largo tiempo tratando de usar varias versiones del @helper item(Func<object, HelperResult> input) , que encontré en la web, sin éxito. Por eso fui por un enfoque como:

namespace project.MvcHtmlHelpers { public static class HelperExtensions { public static MvcHtmlString RazorToMvcString(this HtmlHelper htmlHelper, Func<object, HelperResult> template) { return MvcHtmlString.Create(template.Invoke(null).ToString()); } } }

y

@project.MvcHtmlHelpers @helper item(other input, MvcHtmlString content) { <div class="item"> ...other stuff... <div class="content"> @content </div> </div> }

y usa esto via

@item(other input, @Html.RazorToMvcString(@<text>this is a test</text>))

Ahora puedo usar la plantilla auxiliar para ambas entradas de Razor, pero también puedo soltar vistas parciales, lo cual es útil en algunos puntos. Como no soy un experto, podría haber mejores opciones, pero me parece un enfoque flexible.