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>

4 Answers 4

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.

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

Comments

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".

Comments

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;
  });

Comments

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.

Comments

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.