Skip to content Skip to sidebar Skip to footer

Angular - Watch For Ngshow/nghide Changes In Ancestors That Affect Child Dom Element's Visibility

I am a DOM element (bound to, say, a table). I am the downstream child of an ngShow-based tabs control. I live on the second tab. When the page is rendered, I exist but I am not

Solution 1:

Since you have a scope available in the directive, you could use this to watch for changes in visibility:

scope.$watch(function() { return element.is(':visible') }, function() {
  // Do whatever should happen when the visibility changes
});

This avoids polling the visibility, which could be a performance hit. Of course, this assumes that the scope is applied by whatever causes the visibility to change. I've tried it in my own directive, but not related to ngShow/ngHide.

Credit where credit is due: this was originally proposed (not by me) here: https://groups.google.com/d/msg/angular/w7Gxa5M_17M/koYCZnsobawJ

EDIT 2014-02-24 Revisiting this answer a few months laters, I have noticed that this works but will slow down your digest cycle quite a bit. Best practice is to not use expensive functions such as this for dirty checking. Use with caution!

Solution 2:

The best way I found:

link: function (scope, element, attr) {
    attr.$observe('ngShow', function (expr) {
        scope.$watch(function () {
            return$parse(expr)(scope);
        }, function (value) {
            console.log(value)
        })
    });
}

Good Luck!

Solution 3:

I did this with a directive:

Elemement:

<test-directiveng-show="showMe"show-model="showMe"></test-directive>

Directive:

app.directive('testDirective', function() {
    return {
        restrict: 'E',
        scope: {
            showModel: "=?",
        },
        controller: function($scope) {
            if (angular.isDefined($scope.showModel)) {
                $scope.$watch('showModel', function(newValue, oldValue) {
                    // Do stuff
                });
            }
        }
     }
});

So the idea is to put a $watch on the same variable linked to ng-show.

Solution 4:

The only thing I can think to do is create a directive that loops to see if the element is visible. Something like:

angular.module('testModule', [])
  .directive('onVisible', ['$timeout', function($timeout) {
    return {
      restrict: 'A',
      scope: {
        onVisible: '&'
      },
      link: function(scope, element, attrs) {
        var checkVisibility = function() {
              if (element.is(':visible')) {
                scope.onVisible();
              } else {
                $timeout(checkVisibility, 100);
              }
            };
        $timeout(checkVisibility, 100);
      }
    };
  }]);

Of course, if you need it to execute every time the element becomes visible, you would also need to watch for the element transitioning back to hidden.

Edit: This assumes you have jQuery available.

Solution 5:

Another possible way can be using $broadcast. When your tab is selected, you can broadcast an event

$scope.$broadcast('secondTabSelected');

You can handle this event inside your controller and do further processing.

$scope.$on('secondTabSelected', function(e){
    // do something awesome.
})

This will notify you each time the tab is visible. For executing it only once, you can do

var firstTimeSelected = false;
$scope.$on('secondTabSelected', function(e){
    if(firstTimeSelected){
        firstTimeSelected = true;
        // do something awesome
    }
})

Post a Comment for "Angular - Watch For Ngshow/nghide Changes In Ancestors That Affect Child Dom Element's Visibility"