javascript - 如何使用SlickGrid和DataView在不分组的情况下计算总计?

标签 javascript jquery grouping slickgrid dataview

我正在尝试使用 Slick Grid 和 DataView 来计算列总计,如下例所示:http://mleibman.github.io/SlickGrid/examples/example-grouping 。但是,我不想对行进行分组,因此我尝试不将 getter 和格式化程序传递给 dataView.setGrouping(..) 方法,但在我的表中,它显示带有文本“未定义”的分组行。它确实正确计算了我的总数。如何删除不必要的分组行?

这就是我正在尝试的:

dataView.setGrouping({
    aggregators: [
        new Slick.Data.Aggregators.Sum('someField1'),
        new Slick.Data.Aggregators.Sum('someField2')
    ]
});

最佳答案

因此,对于“如何在不分组的情况下计算总数”的问题,我知道这个问题已经很老了,但由于我必须自己做并且找不到任何有效的方法,所以我决定花一些时间在它上面,现在我正在分享我的解决方案。 SlickGrid 的代码只会计算分组后的总数,我猜这就是聚合器的用途,但我挖掘了 DataView 代码并提出了一个解决方案,它只有几行代码,但效果很好,并且使用了您所使用的 Slick 聚合器已经知道并且已经定义了。我从 DataView 中获取了 2 个函数,其中一些是私有(private)函数,因此您也需要在代码中重新复制它。因此最终代码是 1 个函数名称 CalculateTotalByAggregator() ,它将在内部调用 2 个其他函数。

注意:请注意dataview.getItems()dataview必须是来自您的代码的数据 View ,并且可能拼写不同。

/** Calculate the total of an existing field from the datagrid 
 * @param object aggregator
 * @return mixed total
 */
function CalculateTotalByAggregator(agg) {
  var constructorName = agg.constructor.name; // get constructor name, ex.: SumAggregator
  var type = constructorName.replace(/aggregator/gi, '').toLowerCase(); // remove the word Aggregator and make it lower case, ex.: SumAggregator -> sum

  var totals = new Slick.GroupTotals();
  var fn = compileAccumulatorLoop(agg);
  fn.call(agg, dataview.getItems());
  agg.storeResult(totals);

  return totals[type][agg.field_];
}

/** This function comes from SlickGrid DataView but was slightly adapted for our usage */
function compileAccumulatorLoop(aggregator) {
  aggregator.init();
  var accumulatorInfo = getFunctionInfo(aggregator.accumulate);
  var fn = new Function(
      "_items",
      " for (var " + accumulatorInfo.params[0] + ", _i=0, _il=_items.length; _i<_il; _i++) {" +
          accumulatorInfo.params[0] + " = _items[_i]; " +
          accumulatorInfo.body +
      "}"
  );
  fn.displayName = "compiledAccumulatorLoop";
  return fn;
}

/** This function comes from Slick DataView, but since it's a private function, you will need to copy it in your own code */
function getFunctionInfo(fn) {
  var fnRegex = /^function[^(]*\(([^)]*)\)\s*{([\s\S]*)}$/;
  var matches = fn.toString().match(fnRegex);
  return {
    params: matches[1].split(","),
    body: matches[2]
  };
}

然后在客户端,您只需调用 CalculateTotalByAggregator(agg) 函数和有效的 Slick.Aggregators 对象,例如:

// use any valid Slick Aggregator object and pass it to the function
var agg = new Slick.Data.Aggregators.Sum("Hours");
var totalHours = gridObject.CalculateTotalByAggregator(agg);

// or on a 1 liner
var totalHours = gridObject.CalculateTotalByAggregator(new Slick.Data.Aggregators.Sum("Hours"));

这是几行代码,但这样就不需要重写一个函数来求和,另一个函数来求平均值等等......您只需使用您已经使用的 Slick Aggregators 即可。简单:)

关于javascript - 如何使用SlickGrid和DataView在不分组的情况下计算总计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20753455/

相关文章:

javascript - 异步回调内部调试

javascript - 循环数组仅捕获第一个元素后,在一个文本字段上在线获取多个数据 仅 JavaScript

jquery - jQuery 有类似 :any or :matches pseudo-class? 的东西吗

java - 将多个组存储到集合中

grouping - 使用 jfreechart 创建条形图,并将相同类别的条形图放在一起

javascript - django:将 url 作为参数传递

javascript - jQuery.ajax() 函数中数据选项的用途是什么?

javascript - html 输入工作不正确

javascript - 具有相同id的多个div中的Ajax json值

r - 相互测试所有值并从结果矩阵形成组