剃刀 - 如何将内容呈现为变量

时间:2010-11-28 09:42:28

标签: asp.net-mvc-3 razor

如何在Razor中将一段Html渲染成变量? 在Spark我曾经写过以下代码:

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

将两个变量传递给宏,该宏将内容完美地包装到选项卡表中。

在Razor中做同样事情的最佳方法是什么?

更新:我想我明白了......

在Razor中,@<text>...</text>构造可以是用户生成lambda表达式,可以在以后重用,这是将一段HTML分配给变量的扩展等价物。上面的例子可以通过以下方式实现:

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

我无法弄清楚如何编写无参数的lambdas(Func<object>)。上面两个lambda中的int参数都是假的。 Razor似乎需要一个参数(并且已经创建了一个变量“item”来表达它)。

4 个答案:

答案 0 :(得分:7)

基本上OP已经回答了问题,因为你可以做类似的事情:

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

如果文本仅用于单行,您甚至可以使用“@:”运算符,只需要在下一行中使用分号(或者如果需要任何右括号或括号),如下例所示:

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

但是,如果需要,可以直接将其捕获为字符串

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

你甚至可以将它封装在一个函数中:

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

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

答案 1 :(得分:6)

以防万一其他人发现这篇文章(正如我所做的那样),安迪的更新几乎就在那里。除了给出的示例之外,在给出的示例中访问'int'所需要做的只是引用@item。在@<text></text>块中,变量item包含调用它的模型。

以下是如何使用它的示例:

@model PageData

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

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

在大多数情况下,你应该使用局部视图而不是像这样的函数。但在极少数情况下,部分视图无法实现(例如使用RazorEngine库时),这样可行。

答案 2 :(得分:5)

也许你可以使用HtmlString?我不认为我喜欢这么多,但这就是我试着用你所拥有的精确翻译...

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

所以......我不知道你的Spark宏看起来像什么,但似乎是在Razor中使用帮助器的机会。你可能有类似的东西:

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

然后你可以在你的页面中调用它:

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

答案 3 :(得分:0)

如果您的Razor视图中有IHtmlContentBuilder,则可以使用这些扩展名。

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

用法

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