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
You can consider using transclusion inside a custom directive, to achieve the behavior you are looking for without using 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.
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 .
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.
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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With