ASP.NET MVC3中使用Action <t>作为模板的HtmlHelper:Razor语法?</t>

时间:2011-02-03 06:06:46

标签: asp.net-mvc-3 razor

让我先说一下,或许还有一种更好的方法可以做到这一点,Razor正在照亮道路。在任何情况下,我都有一个HTML帮助程序,它充当各种转发器,但在任意数量的重复之后,它会插入一个备用模板。最明显的用途?在x单元格后开始新行的表。助手看起来像这样:

public static void SeriesSplitter<T>(this System.Web.Mvc.HtmlHelper htmlHelper, IEnumerable<T> items, int itemsBeforeSplit, Action<T> template, Action seriesSplitter)
{
    if (items == null)
        return;
    var i = 0;
    foreach (var item in items)
    {
        if (i != 0 && i % itemsBeforeSplit == 0)
            seriesSplitter();
        template(item);
        i++;
    }
}

在Webforms视图中,用法如下所示:

<table>
    <tr>
    <% Html.SeriesSplitter(Model.Photos, 4, photo => { %>
            <td><img src="<%=ResolveUrl("~/Thumbnail.ashx?id=" + photo.ID)%>" alt="<%=Html.Encode(photo.Title)%>" /></td>
    <% }, () => { %></tr><tr><% }); %>
    </tr>
</table>

在这种情况下,您将拥有一个呈现四个单元格的表,然后使用备用模板(行开始和结束标记)开始一个新行。问题是我无法找到在Razor中完成这项工作的方法。在Razor视图中使用lambda看起来像一个非常奇怪的构造。

你会做什么?

2 个答案:

答案 0 :(得分:2)

菲尔实际上有一个很好的帖子可以解决这个问题:

http://haacked.com/archive/2011/02/27/templated-razor-delegates.aspx

答案 1 :(得分:1)

这是Func<object, HelperResult>的工作(虽然我是从记忆中做到的,所以可能需要调整):

public static void SeriesSplitter<T>(this System.Web.Mvc.HtmlHelper htmlHelper,
                                     IEnumerable<T> items,
                                     int itemsBeforeSplit,
                                     Func<object, HelperResult> template,
                                     Func<object, HelperResult> seriesSplitter) {
    //pretty  much same code here as before
}

然后你会这样称呼它

@Html.SeriesSplitter(Model.Items, 3, @<td>item.Id</td>, @:</td><td>
)

请注意,由于Razor在解析过程中如何进行标记平衡,因此需要@:</td><td>之后的新行