0

I have multiple ng-repeats which use a custom filter and I would like to hide the list. Each list has its own someScopeValue value which is used to determine if a repeated item should be included (or filtered out).

My first attempt doesn't work and it's clear why not (items is only filtered in the ng-repeat and ng-show doesn't know about this:

<!-- this is clearly not smart logic -->
<ul ng-show="items.length">
    <li ng-repeat="item in items | customFilter:someScopeValue">text</li>
</ul>
...
<ul ng-show="items.length">
    <li ng-repeat="item in items | customFilter:someScopeValue">text</li>
</ul>

Is there a way to also apply the filter to the ng-show? Here are some ideas I have but curious if there's a best practice or smarter way to do this:

<!-- this would filter the list somewhere in each <ul> scope -->
<ul ng-show="filteredList.length">
    <li ng-repeat="item in filteredList">text</li>
</ul>

Or, maybe I can use ng-init in some smarter way?

<!-- this filters the list on-the-fly for each <ul> using some scope function -->
<ul ng-init="filteredList = filter(items, someScopeValue)" ng-show="filteredList.length">
    <li ng-repeat="item in filteredList">text</li>
</ul>
d-_-b
  • 21,536
  • 40
  • 150
  • 256

4 Answers4

2

You can created a new variable on your scope that will be the filtered array like this:

<ul ng-show="filteredItems.length">
  <li ng-repeat="item in items | filter:someScopeValue as filteredItems">{{item.value}}</li>
  <li>Extra</li>
</ul>

When doing something like this you will have a $scope.filteredItems created.

JSFIDDLE.

Amir Popovich
  • 29,350
  • 9
  • 53
  • 99
1

If you are not changing the data after you sort the data you could manipulate the array first inside the controller. Then just use your first suggestion of ng-show="filteredList.length".

Jeffrey Jarry
  • 166
  • 2
  • 6
1

Here's the route I went with your question. I set a watch on a list in scope that was being modified by the filter, and based the show on another variable that was holding the length. Here's an example fiddle.

  $scope.counter = $scope.items.length;

  $scope.$watch("items.length", function(newValue, oldValue) { 
    $scope.counter = newValue;
  });
James Cootware
  • 381
  • 2
  • 9
0

Yes, you can use ng-init or introduce a variable in the template. But I would recommend to filter your data inside the controller and expose the filtered array to the template. Especially if you have to hide the parrent <ul> element.

Community
  • 1
  • 1
Sebastian Sebald
  • 16,130
  • 5
  • 62
  • 66