最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Total amount in ng-repeat - Stack Overflow

programmeradmin1浏览0评论

I need helping with calculating the total amount of tickets.number in this ng-repeat

HTML

<tr ng-repeat="tickets in listTickets | filter: searchText | orderBy: sortorder:reverse">
    <td>{{ tickets.match }}</td>
    <td>{{ tickets.number }}</td>
    <td>{{ ticketspany }}</td>
    <td>{{ tickets.contact }}</td>
    <td>{{ tickets.mail }}</td>
    <td>{{ tickets.phone }}</td>
    <td><button class="btn btn-info" ng-click="edit(tickets._id)">Edit</button> </td>
    <td><button class="btn btn-danger" ng-click="delete(tickets._id)">Radera</button></td>   
</tr>
<tr>
    <td colspan="8"> Total of: {{ totalTickets() }} tickets</td>
</tr>

My controller.js

 $scope.totalTickets = function(){

 }

I need helping with calculating the total amount of tickets.number in this ng-repeat

HTML

<tr ng-repeat="tickets in listTickets | filter: searchText | orderBy: sortorder:reverse">
    <td>{{ tickets.match }}</td>
    <td>{{ tickets.number }}</td>
    <td>{{ tickets.pany }}</td>
    <td>{{ tickets.contact }}</td>
    <td>{{ tickets.mail }}</td>
    <td>{{ tickets.phone }}</td>
    <td><button class="btn btn-info" ng-click="edit(tickets._id)">Edit</button> </td>
    <td><button class="btn btn-danger" ng-click="delete(tickets._id)">Radera</button></td>   
</tr>
<tr>
    <td colspan="8"> Total of: {{ totalTickets() }} tickets</td>
</tr>

My controller.js

 $scope.totalTickets = function(){

 }
Share Improve this question edited Dec 20, 2016 at 9:44 clinton3141 4,8413 gold badges35 silver badges47 bronze badges asked Dec 20, 2016 at 9:42 mackeemackeemackeemackee 1714 silver badges16 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 3

You can use ECMAScript 5 Array.prototype.map() and Array.prototype.reduce() to get the total sum.

AngularJS method totalTickets passing the filteredArr array parameter as you are filtering in the view ng-repeat:

$scope.totalTickets = function (filteredArr) {
  return filteredArr
    .map(function (o) {
        return o.number;
    })
    .reduce(function (a, b) {
        return a + b;
    }, 0);
};

AngularJS view:

<tr ng-repeat="tickets in listTickets | filter: searchText as filteredArr | orderBy: sortorder:reverse">
    <td>{{ tickets.match }}</td>
    <td>{{ tickets.number }}</td>
    <td>{{ tickets.pany }}</td>
    <td>{{ tickets.contact }}</td>
    <td>{{ tickets.mail }}</td>
    <td>{{ tickets.phone }}</td>
    <td><button class="btn btn-info" ng-click="edit(tickets._id)">Edit</button></td>
    <td><button class="btn btn-danger" ng-click="delete(tickets._id)">Radera</button></td>   
</tr>
<tr>
    <td colspan="8"> Total of: {{ totalTickets(filteredArr) }} tickets</td>
</tr>

Code example:

var listTickets = [{number: 1},{number: 2},{number: 3},{number: 4}],
    total = listTickets.map(o => o.number).reduce((a, b) => a + b, 0);

console.log(total);

You can also use filter to calculate a total.

Html

<tr ng-repeat="tickets in listTickets | filter: searchText | orderBy: sortorder:reverse">
    <td>{{ tickets.match }}</td>
    <td>{{ tickets.number }}</td>
    <td>{{ tickets.pany }}</td>
    <td>{{ tickets.contact }}</td>
    <td>{{ tickets.mail }}</td>
    <td>{{ tickets.phone }}</td>
    <td><button class="btn btn-info" ng-click="edit(tickets._id)">Edit</button> </td>
    <td><button class="btn btn-danger" ng-click="delete(tickets._id)">Radera</button></td>   
</tr>
<tr>
    <td colspan="8"> Total of: <span data-ng-bind="tickets.total=(listTickets | total:'number')"></span> tickets</td>
</tr>

Controller.js

app.filter('total', function(){
    return function(input, property) {
        var total = 0;
        angular.forEach(input, function(value, key) { total += parseFloat(value[property]) });
        return total;
    }
})

The cleanest solution involves the ngRepeat as keyword (https://docs.angularjs/api/ng/directive/ngRepeat) and a custom total filter as posted by @aravinthan-k.

  • as keyword has to be last in the filter stack in the ng-repeat. Whatever you do in between with different filters, the as alias will have the final result.
  • total filter is easily reusable all over your code.

Fiddle: http://jsfiddle/25g9hzzd/2/

Example HTML:

<div ng-app="myapp">
   <div ng-controller="Ctrl">
        <h1>List</h1>
        <input type="text" ng-model="form.searchText"/>
        <ul>
          <li ng-repeat="item in list | filter: form.searchText as result">
            {{item.title}}
          </li>
          <li>TOTAL: {{result | total:'number'}}</li>
        </ul>
    </div>   
</div>

Example filter (by @aravinthan-k) and the controller:

var app = angular.module('myapp', []);

app.filter('total', function(){
    return function(input, property) {
        var total = 0;
        angular.forEach(input, function(value, key) { total += parseFloat(value[property]) });
        return total;
    }
});

app.controller('Ctrl', function($scope){
    $scope.form = {
        searchText: ''
    };

    $scope.list = [
      {
        title: 'A',
        number: 1
      },
      {
        title: 'AB',
        number: 2
      },
      {
        title: 'ABC',
        number: 3
      },
      {
        title: 'ABCD',
        number: 4
      },
    ];
});

Because you've filtered the list and need to count only the filtered elements, you'll need to pre filter the list in the controller. You can use the search filter in your controller to pre filter the list.

// Inject $filter so that it can be used in the controller
function MyController($filter) {
    $scope.filteredTickets = [];

    // filter the tickets and count how many there are in the filtered list
    function updateTickets(searchTerm) {

        $scope.filteredTickets = $filter('search')($scope.listTickets, $scope.searchText);

        // Use Array.reduce to add up the number of tickets
        $scope.ticketCount = $scope.filteredTickets.reduce(function(count, ticket) {
            return count + ticket.number;
        }, 0);
    }

    // update the ticket count on initialisation
    updateTickets($scope.searchText);

    // update ticket count when search text changes
    $scope.$watch('searchText', function(newValue, oldValue) {
        if (newValue !== oldValue) {
            updateTickets(newValue);
        }
    });
}

Then in your HTML you can ng-repeat through the pre filtered tickets, and use the pre calculated total.

<tr ng-repeat="tickets in filteredTickets | orderBy: sortorder:reverse">
   ...
</tr>
<tr>
    <td>Total of {{ ticketCount }} tickets</td>
</tr>
发布评论

评论列表(0)

  1. 暂无评论