Search code examples
angularjsangularjs-ng-repeatangularjs-filterangular-filters

angularjs - Filter to hide from repeater


I am trying to write a small filter to hide from my repeater elements.

Let's say that my scope is:

$scope.test = [
    {id: 1,name: "Test number 1"},
    {id: 2,name: "Test number 2"},
    {id: 3,name: "Test number 3"},
    {id: 4,name: "Test number 4"},
    {id: 5,name: "Test number 5"},
    {id: 6,name: "Test number 6"},
    {id: 7,name: "Test number 7"},
    {id: 8,name: "Test number 8"},
    {id: 9,name: "Test number 9"},
    {id: 10,name: "Test number 10"} 
]

and in my repeater I am doing something like this:

<div ng-repeat="t in test| hide:[1,6]"></div>

I started to write my filter but I got stuck. This is what I have so far:

filter('hideIDs', function() {
  newArray= [];

  function(zone, IDS) {
    var containsObject, newArray;
    containsObject = function(obj, list) {
      var i;
      i = void 0;
      i = 0;
      while (i < list.length) {
        if (list[i] === obj) {
          return true;
        }
        i++;
      }
      return false;
    };

    angular.forEach(IDS, function(hide) {
      return angular.forEach(test, function(t) {
        if (t.id === hide) {
          return
        } else {
          if (containsObject(t, newArray)) {
            return
          } else {
            newArray.push(t);
          }
        }
      });
    });
    return newArray;
  };
});

What I am trying to do with the filter is:

check if t.id should be hidden, and if yes, return without pushing it to newArray

The problem I've got is:

id to hide is 1 on the first loop, and then 6 gets pushed

on the second loop hovewer, the id to hide is 6 and then 1 gets pushed

And I end up having them both anyway.

Suggestions?

What would you achieve this in an efficient angular way?

thanks a lot


Solution

  • How about this? https://plnkr.co/edit/hPiOnq7jp4kIP6h8Ox1d?p=preview

    <div ng-init="data = [{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}]">
      <div ng-repeat="test in data | hideByIds:[2, 4]">
        {{ test.id }}
      </div>
    </div>
    

    You should reuse what you can, in this case the filter filter:

    var app = angular.module('app', []);
    
    app.filter( 'hideByIds', function( $filter ) {
      return function( input, ids ) {
        return $filter('filter')( input, function( it ) {
          return ids.indexOf( it.id ) == -1;
        } );
      }
    } );
    

    An alternative is to specify the predicate function on the scope, and simply pass it to the filter in the template.