0

I have a tr :

<tr  ng-hide="func(item.status)"  ng-repeat="item in itemArray" >
<td></td>
.
.
</tr>

In the Func() the item.status is compared with the value of a dropdown D which can be changed by the user at any time.

I have a div which i need to show if the current number of visible tr == 0. I am storing the number of visible tr as

$scope.qVisible =  $("#tableid tbody tr:visible").length;

How can i have the qVisible be updated only once all the ng-hide statements have been executed to get the correct result?

Bhumi Singhal
  • 8,063
  • 10
  • 50
  • 76
  • Can you think of a way to do this without querying the dom in your controller? – ganaraj Apr 25 '13 at 08:53
  • i am to just count the number of visible rows. The worst that i can think is that o manually update a var each time func is called ..:( not a good solution – Bhumi Singhal Apr 25 '13 at 08:54

2 Answers2

2

I am going to assume that you have a dropdown somewhere that looks something like..

<select ng-model="selectedStatus" ng-options="status for status in statuses"></select>

So your ng-hide can do something like

<tr  ng-hide="item.status !== selectedStatus"  ng-repeat="item in itemArray" >
<td></td>
.
.
</tr>

In your controller, you need to setup a watch on the selectedStatus..

$scope.qVisible = false;

$scope.$watch("selectedStatus",function(newVal){
    //for loop over items.. counting the number of items that match selectedStatus
    // if count is 0, set a scope variable 
    $scope.qVisible = true;
});

In your html..

<div ng-show="qVisible">...</div>

This is the way to do it without touching the DOM.

ganaraj
  • 26,841
  • 6
  • 63
  • 59
  • @BhumiSinghal I think what you are attempting to do is "premature optimization". Even considering optimization.. querying the DOM is slow.. atleast much slower than running a small for loop. – ganaraj Apr 25 '13 at 09:36
  • ohk ...i already have a loop .. i am now trying to fit in the counting of the var – Bhumi Singhal Apr 25 '13 at 09:49
  • @BhumiSinghal I am assuming you are relatively new to Angular. The best way to learn angular is to actually forget the ways of doing it with JQuery. If you havent already seen it, check this out http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background To start with, you could remove jquery from your project.. Include jquery only when its ABSOLUTELY necessary.. – ganaraj Apr 25 '13 at 09:56
  • Yes i am very new to Angular and yes I would to do it all the angular way only ....but in times of desperate need to turn to jquery ..:) – Bhumi Singhal Apr 25 '13 at 10:12
  • 2
    To be frank, you can build a huge project in angularjs without including jquery. So, its possible. You just need to figure out a way. Dont succumb to the old jquery way of manipulating the DOM. – ganaraj Apr 25 '13 at 10:25
1

You can have $watch that listens to the same as data-ng-repeat runs the same function as hide:

function update(newValue) {
    var i;
    $scope.numberOfShownItems = 0;

    for (i = 0; i < newValue.length; i += 1) {
        if ($scope.func(newValue[i])) {
            $scope.numberOfShownItems += 1;
        }
    }

    $scope.qVisible = !!$scope.numberOfShownItems;
}

$scope.items = [1,2,3,4,5,6];    

$scope.func = function (item) {
    if (item % 2 === 0) {
        return true;
    }

    return false;
}

$scope.$watch('items', update);

Example: http://jsfiddle.net/EgZak/

fredrik
  • 17,537
  • 9
  • 51
  • 71