开发者

ASP.NET MVC Repeater Help

I have built a little repeater HtmlHelper for asp.net MVC and I would like to be able to recurse through to build an tr开发者_StackOverflow社区ee style list. So if <T> has any children that are IEnumerable I would like to add them as embedded lists.

Here is what I have so for which creates a flat list...

    public static MvcHtmlString Repeater<T>(this HtmlHelper html, IEnumerable<T> items,
        Func<T, HelperResult> itemTemplate,            
        Func<string, HelperResult> containerTemplate,
        Func<string, HelperResult> emptyTemplate)
    {
        if (items == null)
            return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(emptyTemplate("No Results").ToHtmlString()));

        if (items.Count() == 0)
            return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(emptyTemplate("No Results").ToHtmlString()));

        StringBuilder sb = new StringBuilder();

        foreach (var item in items)
        {
            string content = itemTemplate(item).ToHtmlString();

            //Here I would want to append the children to 'content' using containerTemplate and itemTemplate....

            sb.Append(HttpContext.Current.Server.HtmlDecode(content));
        }

        return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(containerTemplate(sb.ToString()).ToHtmlString()));
    }

Any help would be greatly appreciated.

Cheers in advance.

Gifster


I would approach this using recursion. I doubt if simply appending the string to content will be enough. You probably need to parse the HTML from the template and insert it into the template in an intelligent fashion depending on whether it's a list or a table, etc. I'm omitting the implementation of that method since I don't know how you expect it to be used. I am showing how to use HtmlAgilityPack, though, for the parsing.

using HtmlAgilityPack;

public static MvcHtmlString Repeater<T>(this HtmlHelper html, IEnumerable<T> items,
    Func<T, HelperResult> itemTemplate,            
    Func<string, HelperResult> containerTemplate,
    Func<string, HelperResult> emptyTemplate)
{
    if (items == null)
        return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(emptyTemplate("No Results").ToHtmlString()));

    if (items.Count() == 0)
        return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(emptyTemplate("No Results").ToHtmlString()));

    StringBuilder sb = new StringBuilder();

    var enumerableProperties = typeof(T).GetProperties()
                                        .Where( p => p is IEnumerable );

    foreach (var item in items)
    {
        var doc = new HtmlDocument();
        doc.LoadHtml( itemTemplate(item).ToHtmlString() );
        var root = doc.DocumentNode.FirstChild;
        var insertNode = FindInsertNode( doc ); // this needs to be written        
        foreach (var property in enumerableProperties)
        {
             var value = property.GetValue( item, null ) as IEnumerable;
             var newNode = new HtmlNode
                           {
                               InnerHtml = html.Repeater( value, itemTemplate, containerTemplate, emptyTemplate )
                           };
             root.InsertAfter( newNode, insertNode );
             insertNode = newNode;
        }
        sb.Append(html.InnerText);
    }

    return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(containerTemplate(sb.ToString()).ToHtmlString()));
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜