javascript angularjs - Angular - Watch for ngShow/ngHide Changes in Ancestors that Affect Child DOM Element's Visibility





documentation examples (5)


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.

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 really visible yet.

I would like to somehow be notified when I become visible through my not-immediate parent, when its ngShow expression becomes true.

Is this possible? I would like to avoid adding code anywhere outside myself - for example, I'd rather not add code in a tab-changed event somewhere. I'd rather have a way to register to find out when, via changes in outermost containers that are bound via ngShow/ngHide, my visibility changes. Can this be done?




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!




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



I did this with a directive:

Elemement:

<test-directive ng-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.




Since you have asynchronous call the way you are trying to write code is not going to work (because by the moment of return returnValue; in the trackCode return value is not yet defined). Instead you should pass callback into trackPage:

function trackPage(callback) {
    var elqTracker = new jQuery.elq(459);
    elqTracker.pageTrack({
        success: function() {
            elqTracker.getGUID(function(guid) {
                alert(guid);
                // Instead of this: var returnValue = guid;
                // You should use your callback function
                callback(guid);
            });
        }
    });
    return returnValue;
}

trackCode(function(guid) {
    // perform some actions with guid
});




javascript angularjs