简体   繁体   English

使用Razor模板创建具有n个列的表

[英]Create a table with n number of columns using a Razor template

I need to create a table of data where I know the number of rows that will be present, but the number of columns will vary. 我需要创建一个数据表,在该表中我知道将要出现的行数,但是列数会有所不同。 The table will exist inside of a razor template. 该表将存在于剃刀模板内。

Ideally I would use a single foreach loop to iterate over a collection and inside the loop, I would add a column for each object. 理想情况下,我将使用单个foreach循环来遍历集合,并在循环内为每个对象添加一列。

Here is the way I have it working right now, but this requires one loop per row. 这是我现在使用它的方式,但这需要每行一个循环。 With 30ish rows, this is not an ideal solution. 对于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>

NOTE: I use an HTML table in my example but that is not a requirement. 注意:我在示例中使用HTML表,但这不是必需的。 Only that the data is displayed in a table like output. 只是数据显示在类似于输出的表中。

EDIT: Here's a fiddle example of the output for 2 objects. 编辑:这是2个对象的输出的小提琴示例。 http://jsfiddle.net/rked00dr/ . http://jsfiddle.net/rked00dr/ Here's an example for 3 objects. 这是3个对象的示例。 http://jsfiddle.net/rked00dr/2/ http://jsfiddle.net/rked00dr/2/

What you're looking for is calling data pivoting. 您正在寻找的是数据透视。 Rather trying to generate it in Razor view you can handle this in your Controller and use pivoted data to avoid the complexity that you already mentioned. 与其尝试在Razor视图中生成它,不如在控制器中处理它并使用透视数据来避免已经提到的复杂性。

Let say your data looks like: 假设您的数据如下所示:

            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");

Note: Don't worry about this initialization I used list extension to get this done. 注意:不用担心此初始化,我使用列表扩展来完成此操作。

Use a function like below though it's not the best approach to Pivot data but it'll do the needful. 使用如下所示的函数,尽管它不是处​​理数据透视表的最佳方法,但可以满足需要。 Create an extension method like below. 创建如下的扩展方法。 Make sure you replace the List<Entity> to you type. 确保替换要输入的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;
    }
}

Now you can simply call this function to your collection. 现在,您可以简单地将此函数调用到集合中。

  <table>
    foreach (var item in oCollection.ToPivot())
    {
       <tr>
        <td>
           @item.Property;
        <td>
        foreach (var value in item.Values)
        {
            <td>
                @value;
           </td>
        }
       <tr>
    }
  </table>

Output: 输出:

+---------+---------------+---------------+-----+
| Id      | 1             | 2             | ... |
| Name    | Thing1        | Thing2        | ... |
| Address | WithAddress_1 | WithAddress_2 | ... |
+---------+---------------+---------------+-----+

my suggested generic version (as per comment below -> jim): 我建议的通用版本(根据下面的评论-> 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);
    }
}

this would allow you to only have to iterate the collection once to build your columns.. 这将使您只需要迭代一次即可构建您的列。

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

If you want to get functional, you could do something like this. 如果您想获得功能,可以执行以下操作。 Where oCollectionItem is whatever type is in oCollection 其中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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM