自定义Kendo UI网格页脚 - 动态更新

时间:2014-03-28 14:32:04

标签: kendo-ui telerik kendo-grid

我需要在Kendo UI Grid页脚模板中显示自定义计算。内置聚合不会满足业务需求。我找到了一种方法,使用下面显示的代码片段显示页脚模板中函数的结果。这段代码的关键点是:

  1. 已定义自定义计算功能(名为calc)。
  2. footerTemplate中存在对自定义计算函数的引用(即footerTemplate:" Total:#= window.calc()#")。

  3. function calc() {
      // assume this to be dynamically determined  
      var field = "Value";
    
      // assume this to be dynamically determined
      var dataSource = window.ds;
    
      // some custom calc logic
      var newValue = 0;
    
      $.each(dataSource.data(), function(index, model) {
          newValue += model.get(field);
      });
    
      return newValue;
    }
    
    $(document).ready(function() {
        window.ds = new kendo.data.DataSource({
          data: [
            {Name:"One", Value:1},
            {Name:"Two", Value:1},
            {Name:"Three", Value:1},
            {Name:"Four", Value:1},
            {Name:"Five", Value:1}
          ],
          pageSize: 10,
          schema: {
            id: "Name",
            fields: {
              Name: { type: "string"},
              Value: { type: "number"}
            }                      
          }
        });
    
        $("#grid").kendoGrid({
            dataSource: window.ds,
            scrollable: false,
            pageable: true,
            editable: true,
            columns: [
              { field: "Name", title: "Name" },
              { field: "Value", title: "Value", 
               footerTemplate: "Total: #=window.calc()#" }
            ]
        });
    });
    

    我遇到的问题是,当用户更改列中的某个值时,需要即时更新计算值。在Kendo UI Grid API中,这似乎并不是一种简单明了的方法。

    我到目前为止所做的是向Grid添加一个保存处理程序,它调用Grid的刷新方法。

        $("#grid").kendoGrid({
            dataSource: window.ds,
            scrollable: false,
            pageable: true,
            editable: true,
            columns: [
              { field: "Name", title: "Name" },
              { field: "Value", title: "Value", 
               footerTemplate: "Total: #=window.calc()#" }
            ],
            save: function (e) {
              e.sender.refresh();
            }
        });
    

    这可行(页脚值在用户更改列中的值后立即更新),但它有一个缺点。当更改值然后单击列中的另一个单元格时,新单击的单元格不会立即进入编辑模式(此功能显然是通过调用刷新方法而短路的)。然后,用户必须再次单击该单元格以使其进入编辑模式(哎呀!)。

    http://trykendoui.telerik.com/oVEV/4有一个代码的工作示例。

    到目前为止我所拥有的解决方案并不理想。有谁知道这个问题更优雅的解决方案?

2 个答案:

答案 0 :(得分:8)

试试这个...用这个替换你的页脚模板:

footerTemplate: "Total:<span id='myId'> #=window.calc()#</span>"

请注意我如何将带有ID的span元素放入其中?这样可以在需要时轻松更改和更新总计。我给了它一个myId

的ID

现在我认为您希望在每次单元格编辑后更新总计(并不一定在保存网格时)。每次成功编辑单元格时,都会在kendo dataSource上触发change事件。因此,在更改事件中重新开始重新计算。您的数据源现在看起来像这样:

window.ds = new kendo.data.DataSource({
     data: [
         //omitted code...
     ],
     pageSize: 10,
     schema: {
         //omitted code...               
     },
     change: function(e){
          var total = window.calc();
          $("#myId").html(total.toString());
     }
});

无需在网格上调用那种丑陋的刷新;)。这是您的revised sample

答案 1 :(得分:1)

提供了很好的解决方案,我尝试了全部。但是我认为只要准备好就可以了。如果设置网格的对象项,则会调用页脚模板。这将更新网格,HTML和Excel中的数据。

let grid = $('#grid').getKendoGrid(); // Kendo Grid
let dataItem = grid.dataItem(tr); // tr: JQuery (selected Row) get Item
let index= grid.items().index(grid.select()); // Selected Row get Row Index in DataSource of the Grid
let rowItem = grid.dataSource.at(index);

dataItem = data.length > 0 && data.length === 1 ? data : dataItem; // data is the new item with the same properties as the item datasource of the Grid.
dataItem.dirty = true;
// You can update all properties with the below code or just one it depends what you want to do. Aggregate functions will be called and Groupfooter and footer also.
for (let [key, value] of Object.entries(dataItem )) {
    rowItem.set(key, value); //

}