开发者

HtmlHelper in ASP.NET MVC3 that uses Action<T> as template: Razor syntax?

Let me preface this by saying that perhaps there's a better way to do this, and Razor is lighting the way. In any case, I have an HTML he开发者_高级运维lper that acts as a repeater of sorts, but after an arbitrary number of repeats, it inserts an alternate template. Most obvious use? Tables that start a new row after x cells. The helper looks like this:

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

And in a Webforms view, the usage looks like this:

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

In this case, you'd have a table that renders four cells, then starts a new row by using the alternate template (the row start and end tags). The problem is that I can't find a way to make this work in Razor. Using a lambda inside of a Razor view seems like a pretty weird construct.

What would you do?


Phil actually had a good post that solves the problem here:

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


This is a job for Func<object, HelperResult> (though I'm doing this from memory so it might need tweaking):

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
}

Then you would call it like so

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

Just note that because of how Razor does tag balancing during parsing you need the new line after @:</td><td>

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜