【问题标题】:Dynamic Kendo grid columns from response data来自响应数据的动态剑道网格列
【发布时间】:2018-03-07 23:40:48
【问题描述】:

我一直在尝试创建一个 Kendo 网格,其中包含基于日期项的动态列值作为响应数据的一部分。

我的数据是这样的:

[
    { Date: '01-01-2018', Name: 'Foo', Value: 1000},
    { Date: '02-01-2018', Name: 'Foo', Value: 2000},
    { Date: '03-01-2018', Name: 'Foo', Value: 3000},
    { Date: '01-01-2018', Name: 'Bar', Value: 1400},
    { Date: '02-01-2018', Name: 'Bar', Value: 2000},
    { Date: '03-01-2018', Name: 'Bar', Value: 5000}
]

我对网格的预期结构如下:

| Name |  Jan | Feb  | Mar  |
|------|------|------|------|
| Foo  | 1000 | 2000 | 3000 |
| Bar  | 1400 | 2000 | 5000 |

我查看了https://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/various/create-with-dynamic-columns-and-data-types,但这并不是我想要做的,它要求我将列作为响应的一部分发送。

我正在使用 GridOptions 的包装器,它通过静态定义的 json 填充列。由于我的列是动态的,因此在此处定义它们时遇到了问题。

最重要的是,除了暴力破解值并将所有唯一日期条目存储为列之外,我无法选择日期的值。如果我有它们,那么如何将它们与正确的数据条目匹配以在网格中显示正确的值?

【问题讨论】:

    标签: kendo-ui kendo-grid kendo-ui-grid


    【解决方案1】:

    您可以使用 kendo ui PivotGrid 组件。它是为处理分类数据而构建的。但是,您可能会发现这会占用大量空间。

    这就留下了自己手动旋转数据的任务。如果您假设所有数据中的Date 值永远不会有两个不同年份的一个月(如果有 01-01-2018 和 01-01-2017 它们都是一月),那么这项任务相对简单每个日期/名称组合只有一行。 (如果日期/名称有两个值,您必须决定如何处理该值?最小值、最大值、第一个、最后一个、意思?)

    data = 
    [
        { Date: '01-01-2018', Name: 'Foo', Value: 1000},
        { Date: '02-01-2018', Name: 'Foo', Value: 2000},
        { Date: '03-01-2018', Name: 'Foo', Value: 3000},
        { Date: '01-01-2018', Name: 'Bar', Value: 1400},
        { Date: '02-01-2018', Name: 'Bar', Value: 2000},
        { Date: '03-01-2018', Name: 'Bar', Value: 5000}
    ];
    
    // distinct month nums over all data
    months = [];
    data.forEach(function(item) {
      var parts = item.Date.split('-');
      var month = parts[0] - 1;
      if (months.indexOf(month) == -1) months.push(month);
    });
    
    // sort and convert month num to month name (for columns)
    months.sort();
    months.forEach(function(monthNum,index,arr) {
      arr[index] = new Date(2018,monthNum,1).toLocaleString("en-US", { month: "short" });
    });
    
    function mmddyyyyToMon(mmddyyyy) {
      var parts = mmddyyyy.split("-");
      var jsMonth = parts[0] - 1;
      var jsDay = parts[1];
      var jsYear = parts[2];
      return new Date(jsYear,jsMonth,jsDay).toLocaleString("en-US", { month: "short" });
    }
    
    // helper to make sure pivot item has one field for every month observed over all data
    function newPivotItem () {
      var result = { Name: '' };
      months.forEach(function(month) {
        result[month] = undefined;
      })
      return result;
    }
    
    // presume data grouped by Name and ordered by month within
    var pivotData = [];
    var pivotItem = {};
    data.forEach (function (item) {
      var parts = item.Date.split("-");
      var jsMonth = parts[0] - 1;
      var jsDay = parts[1];
      var jsYear = parts[2];
      var month = new Date(jsYear,jsMonth,jsDay).toLocaleString("en-US", { month: "short" });
    
      if (pivotItem.Name != item.Name) {
        // start next group of data for a name
        pivotItem = newPivotItem();
        pivotData.push(pivotItem);
        pivotItem.Name = item.Name;
      }
    
      // set value for month for the name
      pivotItem[month] = item.Value;
    })
    
    console.log (pivotData);
    

    【讨论】:

      【解决方案2】:

      我希望这对你有帮助。 我为您制作了一个道场并粘贴了下面的代码以供将来使用。 我使用了为读取提供回调传输的可能性。

      https://dojo.telerik.com/imeNOdUh/2

      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="utf-8">
        <title>Untitled</title>
      
        <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.common.min.css">
        <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.rtl.min.css">
        <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.default.min.css">
        <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.mobile.all.min.css">
      
        <script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
        <script src="https://kendo.cdn.telerik.com/2018.1.221/js/angular.min.js"></script>
        <script src="https://kendo.cdn.telerik.com/2018.1.221/js/jszip.min.js"></script>
        <script src="https://kendo.cdn.telerik.com/2018.1.221/js/kendo.all.min.js"></script></head>
      <body>
        <div id="my-grid"></div>
      
        <script>
      
          function fetchData(success, fail) {
              success([
              { Date: '01-01-2018', Name: 'Foo', Value: 1000},
              { Date: '02-01-2018', Name: 'Foo', Value: 2000},
              { Date: '03-01-2018', Name: 'Foo', Value: 3000},
              { Date: '01-01-2018', Name: 'Bar', Value: 1400},
              { Date: '02-01-2018', Name: 'Bar', Value: 2000},
              { Date: '03-01-2018', Name: 'Bar', Value: 5000}
            ]); 
          }    
      
          var $gridElement = $('#my-grid');
          $gridElement.kendoGrid({
              dataSource: {
                  transport: {
                  read: function(options) {
      
                    fetchData(function(data) {
      
                      // get month names
                      var monthNames = data
                          .map(function(t) {
                          var monthName = kendo.format("{0:MMM}", kendo.parseDate(t.Date, 'MM-dd-yyyy'));
                          return monthName;
                        })
                          .reduce(function(p, t) {
                              if (p.indexOf(t) == -1)
                              p.push(t);
      
                              return p;                        
                        }, []);
      
                      // transform
                      var result = data.reduce(function(p, t) {
                          var monthName = kendo.format("{0:MMM}", kendo.parseDate(t.Date, 'MM-dd-yyyy'));
      
                        var existing = p.filter(function(t2) {
                          return t2.Name == t.Name;
                        });
      
                        if (existing.length) {
                          existing[0][monthName] = t.Value;
                        } else {
                          var n = {
                              Name: t.Name
                          };
                          monthNames.forEach(function(m) {
                            n[m] = 0;
                          });
      
                          n[monthName] = t.Value;
                          p.push(n);
                        }
      
                        return p;
                      }, []);
      
                      options.success(result);
      
                    });
      
      
                  }
                }
              }
          });
      
        </script>
      </body>
      </html>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多