How to sum in each row the values of before rows in specific column?

时间:2015-07-31 19:31:01

标签: angularjs

I've simulated my problem in this fiddle.

I have this HTML:

<table ng-app='Payments'>
    <thead>
        <tr>
            <th>Date</th>   <th>Cash</th>   <th>Total</th>
        </tr>
    </thead>
    <tbody ng-controller='paymentsController'>
        <tr ng-repeat='pay in payments | orderBy : "date"'>
            <td>{{pay.date}}</td>
            <td><input type="textbox" ng-model="pay.cash"/></td>
            <td></td>
        </tr>
    </tbody>
</table

And this JS:

var appModule = angular.module('Payments', []);

appModule.controller('paymentsController', function($scope) {
    $scope.payments = [
        {'id' : '1', 'date' : '2015-07-27', 'cash' : '149.98'},
        {'id' : '2', 'date' : '2015-07-29', 'cash' : '70.00'},
        {'id' : '3', 'date' : '2015-07-27', 'cash' : '129.99'},
        {'id' : '4', 'date' : '2015-07-28', 'cash' : '349.90'}
    ];
});

How do I fill the third column with Angular?

The third column should be initially:

149.98       // due to   0.00 + 149.98
279.97       // due to 149.98 + 129.99
629.87       // due to 279.97 + 349.90
699.87       // due to 629.87 +  70.00

Then, ng-model should do the trick to update them automatically later.

Thanks in advance.

2 个答案:

答案 0 :(得分:2)

You could add a function to the scope to calculate the total at that index. You have to keep in mind that you are using order by which means you should us the as syntax to calculate the value from the ordered list.

CalculatePay function:

$scope.calculatePay = function(index) {
  var sum = 0;
  for(var i = 0; i <= index; i++) {
    sum += parseFloat($scope.orderedList[i].cash);
  }
  return sum;
};

html:

<table ng-app='Payments'>
    <thead>
        <tr>
            <th>Date</th>   <th>Cash</th>   <th>Total</th>
        </tr>
    </thead>
    <tbody ng-controller='paymentsController'>
        <tr ng-repeat="pay in payments | orderBy: 'date' as orderedList track by pay.id">
            <td>{{pay.date}}</td>
            <td><input type="textbox" ng-model="pay.cash"/></td>
            <td>{{calculatePay($index)}}</td>
        </tr>
    </tbody>
</table>

track by is also helpful if the id is truely unique

Example: http://plnkr.co/edit/igBGY1h5RIKMNkncxhp6?p=preview

答案 1 :(得分:2)

You would need to handle sorting in code, as the orderBy in ng-repeat creates a new list used for the display, and doesn't modify the original list. This would mean that the indexes of items in the display list don't match up with that in the original list. You'll also need a watcher on the payments collection to automatically update the totals at each position.

Something like

$scope.$watch('payments', function(newPayments) {
    $scope.payments = orderByFilter($scope.payments, "date");
    $scope.total = 0;
    angular.forEach($scope.payments, function(payment) {
        $scope.total += parseFloat(payment.cash);
        payment.total = $scope.total;
    });
}, true);

Fiddle: http://jsfiddle.net/29mh8bfe/4/