当前位置: 动力学知识库 > 问答 > 编程问答 >

angularjs - Angular: Count items matching a condition

问题描述:

I have this array of items

[

{

name: 'Foo',

completed: false

},

{

name: 'Ninja',

completed: true

},

{

name: 'Hello',

completed: true

},

{

name: 'Baby',

completed: false

},

]

I'd like to display the count where completed = true in my view. I also need this counter to update automatically when an element goes from completed=false to true.

Is there a way to do this in angular?

网友答案:

You should look about filter and use it to filter dynamically your array; In your controller declare your filter like this

$scope.completedFilter(object) {
    return object.completed === true;
}

After in your template you can just add

{{(myArray | filter:completedFilter).length}}

And your count will be automatically changed with the completed

Note: you can also declare a filter in you module that could be proper if you want to reuse it in another controller

网友答案:

There are a number of approaches you could take, but they all start by caching the count of the number of items that are completed when the controller loads.

You could use the $watch function to monitor the array, and update a counter when the object changes. The following is untested, but should give you a sense of how to do it

function myCtl($scope, itemFetcher) {
  $scope.items = itemFetcher.get(); //retrieves your array of items
  $scope.numComplete = countComplete();

  $scope.$watch("items", function(newValue, oldValue) {
    $scope.items = newValue;
    $scope.numComplete = countComplete();
  }, true); // NOTE: passing true into $watch is necessary to do a deep compare (i.e. comparing object properties), and I think it is required in this case, but it has a negative impact on performance & memory.

  function countComplete() {
    var cnt = 0;
    angular.forEach($scope.items, function(item) {
      cnt += item.completed ? 1 : 0;
    }
    return cnt;
  }
}

Alternatively, you can update the completed count in functions that modify the items completed state. The following code is also untested.

function myCtl($scope, itemFetcher) {
  $scope.items = itemFetcher.get(); //retrieves your array of items
  $scope.numComplete = countComplete();

  $scope.markItem = function(index, newState) { // this function is referenced in your HTML template
    $scope.items[index].complete = newState;
    $scope.numComplete += (newState) ? 1 : -1;
  }

  function countComplete() {
    var cnt = 0;
    angular.forEach($scope.items, function(item) {
      cnt += item.completed ? 1 : 0;
    }
    return cnt;
  }
}

Using $watch is more convenient and less error-prone, but may cause performance issues depending on the size of the items array. The second approach is more efficient, but tougher to maintain.

网友答案:

Is adding a $watch necessary ?

Try this way

 $scope.itemCount = function () {
    var cnt = 0;
    angular.forEach($scope.items, function (item) {
        cnt += item.completed ? 1 : 0;
        console.log(item);
    });
    return cnt;
}

Just to check the count is getting updated i added an item on button click to items array

$scope.insertItem = function () {
    $scope.items.push({ name: 'Phani', completed: true });

}
{{itemCount()}}

    <input type="button" ng-click="insertItem()" value="Insert" />

Try the above approach

分享给朋友:
您可能感兴趣的文章:
随机阅读: