Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I only show an element if nested ng-repeat is not empty?

I have a List of lists, created with a nested ng-repeat. Each outer ng-repeat contains a div with the label of its inner list (eg: "Group A"). I'm now trying to create a way to avoid showing this label if the inner list is empty due to filtering(Applied by an input searchtext)

Here is a plunker explaining my issue and my attempted solution : Plnkr

Having a 'heavy' function like isGroupEmpty seems extremely cumbersome - Is there any way to do this in a much simpler fashion? I was toying with the idea of moving the label inside the inner ng-repeat and having ng-show="$first" but it doesnt look great

like image 855
CodePrimate Avatar asked Nov 15 '13 13:11

CodePrimate


People also ask

What can I use instead of NG-repeat?

You can consider using transclusion inside a custom directive, to achieve the behavior you are looking for without using ng-repeat.

How do I get the index of an element in NG-repeat?

Note: The $index variable is used to get the Index of the Row created by ng-repeat directive. Each row of the HTML Table consists of a Button which has been assigned ng-click directive. The $index variable is passed as parameter to the GetRowIndex function.

Where is the last element in NG-repeat?

You can use $last variable within ng-repeat directive. Take a look at doc. Where computeCssClass is function of controller which takes sole argument and returns 'last' or null .

Does ng-repeat create a new scope?

Directives that Create Scopes In most cases, directives and scopes interact but do not create new instances of scope. However, some directives, such as ng-controller and ng-repeat, create new child scopes and attach the child scope to the corresponding DOM element.


2 Answers

I ended up with the following solution which worked perfectly. Plnkr

By setting a variable in the inner ng-repeat I was able to evaluate ng-show based on this variables length like so :

<input ng-model='searchText'/> <span ng-show='filtered.length > 0'>   <ul>     <li ng-repeat='el in filtered = (model | filter:searchText)'>       <div>{{el.label}}</div>     </li>   </ul> </span> 
like image 65
CodePrimate Avatar answered Oct 07 '22 00:10

CodePrimate


you could leverage ng-init, that way you'll call the filter only once:

<div ng-repeat='(key,group) in model'>   <div ng-init="filtered = (group | filter:filterFn)"></div>   <div ng-show="filtered.length !== 0">     <div>{{key}}</div>     <ul>       <li ng-repeat="el in filtered">         <div>{{el.label}}</div>       </li>     </ul>   </div>  </div> 

usually it is not a good practice to use ng-init out of no where, but I guess it solves calling the filter twice. Another way is to use the filter through javascript - you could inject $filter and retrieve 'filter' $filter('filter') in your controller, calling it with group as its first argument, the filterFn as its second, and store its result in your scope.

like image 26
surui Avatar answered Oct 07 '22 00:10

surui