我已经为asp.net MVC构建了一个小的转发器HtmlHelper,我希望能够通过递归来构建一个树样式列表。因此,如果<T>
有任何IEnumerable
子项,我想将它们添加为嵌入列表。
这就是我所拥有的,它创建了一个平面列表......
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()));
}
非常感谢任何帮助。
提前干杯。
Gifster
答案 0 :(得分:1)
我会使用递归来解决这个问题。我怀疑是否只是将字符串附加到内容就足够了。您可能需要从模板中解析HTML并以智能方式将其插入到模板中,具体取决于它是列表还是表格等。我省略了该方法的实现,因为我不知道您的期望它被使用。我将展示如何使用HtmlAgilityPack进行解析。
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()));
}