使用Razor模板创建一个包含n列的表
本文关键字:包含 一个 Razor 创建 使用 | 更新日期: 2023-09-27 18:19:15
我需要创建一个数据表,其中我知道将出现的行数,但列数将变化。该表将存在于razor模板中。
理想情况下,我会使用单个foreach循环来遍历集合,并且在循环中,我会为每个对象添加一列。
这是我现在让它工作的方式,但这需要每行一个循环。对于大约30行,这不是一个理想的解决方案。
<table>
<tr>
@foreach(var o in oCollection)
{
<td>@o.Name</td>
}
</tr>
<tr>
@foreach(var o in oCollection)
{
<td>@o.Id</td>
}
</tr>
<tr>
@foreach(var o in oCollection)
{
<td>@o.Address</td>
}
</tr>
</table>
注意:我在我的例子中使用了一个HTML表,但这不是必需的。只是数据显示在类似output的表中。
编辑:下面是2个对象的输出示例。http://jsfiddle.net/rked00dr/。下面是3个对象的例子。http://jsfiddle.net/rked00dr/2/
您正在寻找的是调用数据透视。比起在Razor视图中生成它,你可以在你的控制器中处理它,并使用pivot数据来避免你已经提到的复杂性。
假设你的数据看起来像:
var list = new List<Entity>();
list.Add(1, "Thing1", "WithAddress_1");
list.Add(2, "Thing2", "WithAddress_2");
list.Add(3, "Thing3", "WithAddress_3");
list.Add(4, "Thing4", "WithAddress_4");
list.Add(5, "Thing5", "WithAddress_5");
list.Add(6, "Thing6", "WithAddress_6");
注意:不要担心这个初始化,我使用列表扩展来完成这个。
使用下面的函数,虽然它不是Pivot数据的最佳方法,但它将完成必要的工作。创建如下所示的扩展方法。确保将List<Entity>
替换为您的类型。
Public static class ListExtensions
{
Public static IEnumerable<dynamic> ToPivot(this List<Entity> oCollection)
{
List<dynamic> parent = new List<dynamic>();
List<dynamic> extended = null;
foreach (Entity entity in oCollection)
{
extended = new List<dynamic>();
foreach (var prop in entity.GetType().GetProperties())
{
extended.Add(new { Property = prop.Name, Value = prop.GetValue(entity) });
}
parent.AddRange(extended);
}
// Grouping of value by property names, so each property
// represents list of all values w.r.t to that property in given list.
var grps = from d in parent
group d by d.Property
into grp
select new
{
Property = grp.Key,
Values = grp.Select(d2 => d2.Value).ToArray()
};
return grps;
}
}
现在您可以简单地将这个函数调用到您的集合中。
<table>
foreach (var item in oCollection.ToPivot())
{
<tr>
<td>
@item.Property;
<td>
foreach (var value in item.Values)
{
<td>
@value;
</td>
}
<tr>
}
</table>
输出:+---------+---------------+---------------+-----+
| Id | 1 | 2 | ... |
| Name | Thing1 | Thing2 | ... |
| Address | WithAddress_1 | WithAddress_2 | ... |
+---------+---------------+---------------+-----+
我建议的通用版本(根据下面的评论-> jim):
public static IEnumerable<dynamic> ToPivot<T>(this IList<T> oCollection)
{
var parent = new List<dynamic>();
try
{
foreach (T entity in oCollection)
{
var extended = new List<dynamic>();
foreach (var prop in entity.GetType().GetProperties())
{
extended.Add(new { Property = prop.Name, Value = prop.GetValue(entity) });
}
parent.AddRange(extended);
}
// Grouping of value by property names, so each property
// represents list of all values w.r.t that property in given list.
var grps = parent.GroupBy(d => d.Property).Select(grp => new
{
Property = grp.Key,
Values = grp.Select(d2 => d2.Value).ToArray()
});
return grps;
}
catch
{
// log the reason perhaps
return default(dynamic);
}
}
这将允许您只需要迭代一次集合来构建列。
@{
string row1;
string row2;
string row3;
foreach (var o in oCollection)
{
row1 += string.Format("<td>{0}</td>", o.Name);
row2 += string.Format("<td>{0}</td>", o.Id);
row3 += string.Format("<td>{0}</td>", o.Address);
}
}
<table>
<tr>
@Html.Raw(row1);
</tr>
<tr>
@Html.Raw(row2);
</tr>
<tr>
@Html.Raw(row3);
</tr>
</table>
如果您想获得功能,您可以这样做。其中oCollectionItem
为oCollection
@{
List<Func<oCollectionItem, string>> funcs = new List<Func<oCollectionItem, string>>(){
x => x.Name,
x => x.Address,
x => x.ID.ToString(),
//repeat for each thing to display
};
}
<table>
@foreach(var func in funcs)
{
<tr>
@foreach(var item in oCollection)
{
<td>@func(item)</td>
}
</td>
}
</table>