从之前的条目计算ng-repeat

时间:2014-05-22 20:19:44

标签: angularjs angularjs-ng-repeat

我有一个已过滤的列表(按时间过滤 - 因此在特定的时间范围内)并且在这些项目上我使用ng-repeat进行迭代。这些物品有名称和价格。因此,如果我在迭代它们,我想实现我总是显示" sub" -total像这样:

DATE       NAME       PRICE      SUBTOTAL
2014-05    T-Shirt    20.00      20.00
2014-05    Jeans      45.00      65.00
2014-05    Cap        15.00      80.00

这些项目按日期排序,但可能有不同的ID(ID与索引不匹配!)。

我真的无法找出如何总是计算小计(表格可以按日期范围过滤,意味着我还可以包含2014-04的项目,它应该动态重新计算。

我在控制器中使用这样的函数尝试了它:

var curBalanceCounter2 = 0;

$scope.currentBalanceCalc = function(finance) {
  curBalanceCounter2 = curBalanceCounter2 + finance.amount;
  return curBalanceCounter2;
}

但是我被执行了10次,所以我得错了号码。有更好的解决方案吗?

谢谢。

4 个答案:

答案 0 :(得分:4)

创建自定义过滤器

myApp.filter('subtotal', function(){
  return function(items, index){
    var subtotal = 0;
    for (var i = 0; i <= index; i++) {
      subtotal += items[i].price
    } 
    return subtotal || items[index].price;
  }
});

并称之为

<li ng-repeat="item in items">{{item.name}} - {{item.price}} -
{{ items | subtotal : $index}}</li>

Demo

由于您可以访问ng-repeat内的原始列表(例如上面代码中的items),因此您可以将其与当前项的索引一起传递到自定义过滤器中。然后,此过滤器可以循环遍历每个项目,包括传入的索引,然后返回求和的小计。如果小计为0(就像第一个项目那样),而是返回该项目的价格。

文档:Custom filters in Angular

答案 1 :(得分:2)

这与Marc的答案类似。在控制器中定义小计函数:

$scope.subtotal = function(index){         
     var total = 0;
     angular.forEach($scope.data, function(value, key){
       if(key <= index)
         total += value.Price;           
     });
     return total;
   }

然后在视图中使用它:

<tr ng-repeat="d in data">
      <td>{{d.Date}}</td>
      <td>{{d.Name}}</td>
      <td>{{d.Price}}</td>
      <td>{{subtotal($index)}}</td>
</tr>

Demo

更新

如果问题是数据尚未在客户端上排序,但是正在按ng-repeat上的过滤器进行排序,那么这是修复: 将orderBy参数传递给小计函数,并在计算小计之前对数据执行过滤:

$scope.orderBy = 'Date';
$scope.subtotal = function(index, orderBy){         
     var total = 0;
     angular.forEach($filter('orderBy')($scope.data,orderBy), function(value, key){
       if(key <= index)
         total += value.Price;           
     });
     return total;
   }

我已使用此代码更新了我的演示。您可以通过在此行上将“日期”更改为“名称”或“价格”来更改排序顺序

$scope.orderBy = 'Date';

并看到小计自动重新计算。

答案 2 :(得分:1)

我不知道有什么方法可以用纯粹的角度来做这件事,也许有人会说话。

您需要的是累积总和:

function cSum(arr) {
  var cumsum = [];

  for(var i=0;i<arr.length;i++) {
    if(i==0) cumsum[i] = arr[0];
    else cumsum[i] = cumsum[i-1] + arr[i];
  }
  return cumsum
}

然后只需将该字段添加到您重复的对象数组中,即可在表格中显示该字段。

答案 3 :(得分:1)

不太难做http://jsfiddle.net/VAJ5S/3/

<强> HTML

<div ng-app="myApp">
    <table ng-controller="myController">
        <thead>
            <tr>
                <th>DATE</th>
                <th>NAME</th>
                <th>PRICE</th>
                <th>SUBTOTAL</th>
            </tr>
        </thead>
        <tr ng-repeat="item in items">
            <td>{{item.date}}</td>
            <td>{{item.name}}</td>
            <td>{{item.price}}</td>
            <td>{{subtotal($index)}}</td>
        </tr>
    </table>
</div>

<强> JS

var app = angular.module("myApp", []);

app.controller("myController", ["$scope", function($scope){
    $scope.items = [
        {
            date: "2014-05",
            name: "T-Shirt",
            price: 20.00
        },
        {
            date: "2014-05",
            name: "Jeans",
            price: 65.00
        },
        {
            date: "2014-05",
            name: "Cap",
            price: 80.00
        }
    ];

    $scope.subtotal = function(ind){
        var subtotal = 0;
        for (var i = 0; i<=ind; i++){
            subtotal += $scope.items[i].price;
        }
        return subtotal;
    };
}]);