简体   繁体   中英

angular hide when filtered array is empty

I have multiple ng-repeat s 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>

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 .

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM