1

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

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

writing in this stile results in 'Why my angular app is too slow?'
@PetrAveryanov can you explain your comment a bit more please? I am really concerned about my app getting slower
filters run each digest - they should be super fast. Filter that operates with 2 array with ~ (m*n) time cant be fast.
@Nick create a new array on the scope with the necessary elements hidden, and only refresh it when the ids (that you want to hide) change.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.