2010-11-28 11 views
14

¿Cómo convertir una pieza de HTML en una variable en Razor? En Spark solía escribir el siguiente código:Maquinilla de afeitar: cómo representar el contenido en una variable

<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)} 

dos variables se pasan a una macro que hace todo el buen envoltorio del contenido en la hoja de la ficha.

¿Cuál es la mejor manera de hacer lo mismo en Razor?

Actualización: Creo que lo tengo ..

En la maquinilla de afeitar, el constructo @<text>...</text> puede ser de uso para producir expresiones lambda, que pueden ser reutilizados después, que es un equivalente prolongado de la asignación de un trozo de HTML a una variable. El ejemplo anterior se puede realizar de la siguiente manera:

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)) 

No puedo encontrar la manera de escribir lambdas sin parámetros (Func<object>). el parámetro int en ambos lambdas arriba es un maniquí. Razor parece necesitar un parámetro (y ya crea un "elemento" variable para indicarlo dentro de la expresión).

Respuesta

5

¿Quizás puedas usar HtmlString? Creo que no me gusta mucho este hecho, pero esto es lo que iba a tratar como una traducción exacta de lo que tiene ...

@{ 
    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) 

Así que ... No sé lo que la macro chispa parece , pero parece una oportunidad para usar un ayudante en Razor. Es posible que tenga algo como:

@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 --> 
} 

Entonces llaman a que a partir de su página, así:

@Tabs("Tab Name", "Here goes tab content") 
+0

gracias, creo que lo que realmente necesita es una sintaxis de línea auxiliar. No creo que esto esté disponible en Razor todavía. la solución sería declarar un ayudante explícito, que se puede llamar y el resultado se puede asignar a una variable. – Andy

+0

Me equivoqué en el comentario anterior. La sintaxis está disponible, no se requieren ayudantes explícitos. Las expresiones Lambda se pueden usar en su lugar. Ver mi pregunta actualizada – Andy

5

Sólo en caso de cualquier otra persona encuentra este post (como yo), Actualización de Andy es casi allí . Además del ejemplo dado, todo lo que tiene que hacer para acceder al 'int' en el ejemplo dado es la referencia @item. En los bloques @<text></text>, la variable item contiene el modelo al que se llamó.

Aquí hay un ejemplo de cómo se puede utilizar:

@model PageData 

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

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

En la mayoría de los casos que es mejor usar una vista parcial en lugar de una función como esta. Pero en los raros casos en que una vista parcial no es posible (como cuando se usa la biblioteca RazorEngine), esto funciona.

+0

Usted señaló un hecho que no es muy conocido, ¡gracias! – Sel

7

Básicamente el PO ya había respondido al problema de que se podía hacer algo como:

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

Si el texto es para una única línea incluso se podría utilizar la "@" operador, simplemente remmebr tener un punto y coma (o si es necesario, los soportes de cierre o paréntesis) en la línea siguiente, como en el siguiente ejemplo:

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

Sin embargo, usted puede capturar directamente como una cadena si quieres

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

Incluso se puede encapsular en una función:

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

@{ 
    string a = ToString(@<text> 
        Some Text 
       </text>); 
    @a //Output directly as a string   
} 
0

Si usted tiene una IHtmlContentBuilder en su opinión, la maquinilla de afeitar, puede utilizar estas extensiones.

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); 
    } 

Uso

@{ 
    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> 
Cuestiones relacionadas