2012-05-17 10 views
18

Busqué pero no encontré ninguna solución rápida para un MVT 3 htmlhelper para crear un método de contenedor. Lo que estoy buscando es algo así como:Método de extensión MVC 3 htmlhelper para envolver contenido

@html.createLink("caption", "url") 
{ 
    <html> content in tags </html> 
} 

el resultado debe tener

<a href="url" title="Caption"> 
    <html> content in tags </html> 
</a> 

Cualquier ayuda con esto.

+0

¿Estás preguntando si es posible hacer algo como esto: '@ Html.ActionLink (" Hola World "," MyAction ")'? – CallumVass

+0

No, no es eso. Sé que hay un tipo de enfoque BeginForm() y EndForm() para manejar este tipo de escenario, pero al hacerlo a gran escala puede causar un problema si se olvida una etiqueta de cierre. – Sanj

+0

No estoy seguro de saber a qué te refieres?¿No usaría 'BeginForm' en este escenario? Utilizarías 'BeginForm' para crear un formulario, no un enlace de anclaje. – CallumVass

Respuesta

42

La forma en que esto se hace con BeginForm es que el tipo de retorno MvcForm impliments IDisposable de manera que cuando se utiliza dentro de una sentencia using, la Dispose método de MvcForm escribe la etiqueta </form> de cierre.

Puede escribir un método de extensión que haga exactamente lo mismo.

Aquí hay una que acabo de escribir para demostrar.

En primer lugar, el método de extensión:

public static class ExtensionTest 
{ 
    public static MvcAnchor BeginLink(this HtmlHelper htmlHelper) 
    { 
     var tagBuilder = new TagBuilder("a"); 
     htmlHelper.ViewContext.Writer 
         .Write(tagBuilder.ToString(
              TagRenderMode.StartTag)); 
     return new MvcAnchor(htmlHelper.ViewContext); 
    } 
} 

Y aquí está nuestro nuevo tipo, MvcAnchor:

public class MvcAnchor : IDisposable 
{ 
    private readonly TextWriter _writer; 
    public MvcAnchor(ViewContext viewContext) 
    { 
     _writer = viewContext.Writer; 
    } 

    public void Dispose() 
    { 
     this._writer.Write("</a>"); 
    } 
} 

En sus puntos de vista ya que puede hacer:

@{ 
    using (Html.BeginLink()) 
    { 
     @Html.Raw("Hello World") 
    } 
} 

Lo que produce el resultado:

<a>Hello World</a> 

ampliación de este poco para hacer frente a sus necesidades exactas:

public static MvcAnchor BeginLink(this HtmlHelper htmlHelper, 
            string href, 
            string title) 
{ 
    var tagBuilder = new TagBuilder("a"); 
    tagBuilder.Attributes.Add("href",href); 
    tagBuilder.Attributes.Add("title", title); 
    htmlHelper.ViewContext.Writer.Write(tagBuilder 
            .ToString(TagRenderMode.StartTag)); 
    return new MvcAnchor(htmlHelper.ViewContext); 
} 

y nuestro punto de vista:

@{ 
    using (Html.BeginLink("http://stackoverflow.com", "The Worlds Best Q&A site")) 
    { 
     @Html.Raw("StackOverflow - Because we really do care") 
    } 
} 

que produce el resultado:

<a href="http://stackoverflow.com" title="The Worlds Best Q&amp;A site"> 
    StackOverflow - Because we really do care</a> 
+2

esto es hermoso. me acabas de salvar medio día :)) –

2

En su nivel más simple algo como esto lo haría

public static MvcHtmlString SomeLink(this HtmlHelper htmlHelper, string href, string  title, string content) 
    { 
     var urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url; 
     //var url = urlHelper.Action(actionName, controllerName, routeValues); 

     var someLink = new TagBuilder("a"); 
     someLink.MergeAttribute("href", href); 
     someLink.InnerHtml = content; 

     return new MvcHtmlString(someLink.ToString()); 
    } 
8

Hay también otra forma sin trucos desechables Es menos trabajo, ideal para pequeños ayudantes. Respondí pregunta similar y no quiero copiar todo, pero aquí hay un pequeño ejemplo:

@helper Paragraph(string cssClass, Func<object, object> markup) { 
    <p class="@cssClass">@markup.DynamicInvoke(this.ViewContext)</p> 
} 

El uso de esta ayuda se ve así:

@Paragraph("highlited", 
    @<text> 
     Look, a @Html.ActionLink("link", "index") 
    </text> 
) 

Mi respuesta completa a la otra pregunta similar here.

Cuestiones relacionadas