2010-11-28 14 views
14

Comment rendre un morceau de Html dans une variable dans Razor? Spark I utilisé pour écrire le code suivant:Razor - comment rendre le contenu dans une 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)} 

deux variables et sont transmis à une macro qui fait tout le joli emballage du contenu dans la feuille de tabulation.

Quelle est la meilleure façon de faire la même chose avec Razor?

Mise à jour: Je pense que je l'ai ..

En rasoir, la construction peut être @<text>...</text> utilisateur pour produire des expressions lambda, qui peuvent être réutilisés plus tard, ce qui est un équivalent étendu d'attribution d'un morceau de HTML à une variable. L'exemple ci-dessus peut être mis en œuvre de la manière suivante:

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

Je ne peux pas comprendre comment écrire lambdas sans paramètre (Func<object>). le paramètre int dans les deux lambdas ci-dessus est un mannequin. Razor semble avoir besoin d'un paramètre (et crée déjà une variable "item" pour le désigner dans l'expression).

Répondre

5

Peut-être pouvez-vous utiliser HtmlString? Je ne pense pas que je l'aime autant, mais voici ce que je vais essayer comme une traduction exacte de ce que vous avez ...

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

Alors ... Je ne sais pas ce que votre macro Spark ressemble , mais cela semble être une opportunité d'utiliser un assistant dans Razor. Vous pourriez avoir quelque chose comme:

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

Ensuite, vous appelez cela de dans votre page comme ceci:

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

merci, je pense que ce que je vraiment besoin est une syntaxe d'aide en ligne. Je ne suis pas encore disponible sur Razor. la solution serait de déclarer un assistant explicite, qui peut être appelé et le résultat pourrait être assigné dans une variable. – Andy

+0

J'avais tort dans le commentaire ci-dessus. La syntaxe est disponible, aucune aide explicite n'est requise. Les expressions lambda peuvent être utilisées à la place. Voir ma question mise à jour. – Andy

5

Juste au cas où quelqu'un d'autre trouve ce post (comme je l'ai fait), la mise à jour de Andy est presque là . En plus de l'exemple donné, tout ce que vous avez à faire pour accéder à 'int' dans l'exemple donné est la référence @item. Dans les blocs @<text></text>, la variable item contient le modèle sur lequel elle a été appelée.

Voici un exemple de la façon dont il peut être utilisé:

@model PageData 

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

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

Dans la plupart des cas, vous devriez probablement utiliser une vue partielle au lieu d'une fonction comme celui-ci. Mais dans les rares cas où une vue partielle n'est pas possible (comme lors de l'utilisation de la bibliothèque RazorEngine), cela fonctionne.

+0

Vous avez fait remarquer que pas bien connu, merci! – Sel

7

Fondamentalement, l'OP déjà répondu le problème que vous pourriez faire quelque chose comme:

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

Si le texte est pour une seule ligne, vous pouvez même utiliser le « @: » opérateur, juste remmebr avoir un point-virgule (ou si elle a besoin des crochets de fermeture ou entre parenthèses) sur la ligne suivante, comme dans l'exemple suivant:

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

Cependant, vous pouvez capturer directement en tant que chaîne si vous voulez

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

Vous pouvez même l'encapsuler dans une fonction:

@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 vous avez un IHtmlContentBuilder dans votre vue de rasoir, vous pouvez utiliser ces extensions.

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

Utilisation

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