Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Watch element's height in angular directive

Tags:

angularjs

I'm trying to $watch an element's height in my directive's link function.

The height of the element is set such that it's (eventually) equal to the window height. So it should change as the window is resized.

However it isn't updating when you resize the window.

angular.module('app', []).directive('element', function($interval) {
  return {
    restrict: 'E',
    link: function(scope, element) {
      scope.$watch(
        function() {
          return element.height();
        },
        function(height) {
          console.log('element updated', element.height());
        });
    },
  };
});
element {
  display: block;
  border: 1px dotted;
}
* {
  height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <element>test</element>
</div>

I have read this related question but I don't understand why they're using 2 directives or how they're turning out to be helpful. I did try two $watches, similar to what they have done there but it also doesn't help.

angular.module('app', []).directive('element', function($interval) {
  return {
    restrict: 'E',
    link: function(scope, element) {
      scope.$watch('__height',
        function(height) {
          console.log('element updated', element.height());
        });
      scope.$watch(
        function() {
          scope.__height = element.height();
        });
    },
  };
});
element {
  display: block;
  border: 1px dotted;
}
* {
  height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <element>test</element>
</div>
like image 483
laggingreflex Avatar asked Mar 02 '26 19:03

laggingreflex


2 Answers

You don't need $watch here. You can simply add resize event handler to $window and apply the window height using window.innerHeight to the element. Make sure $window is injected as dependency.

angular.module('app', []).directive('element', function($interval, $window) {
  return {
    restrict: 'E',
    link: function(scope, element) {
      $window.addEventListener('resize', function() {
          element.css('height', window.innerHeight);
      }, false);
    },
  };
});
element {
  display: block;
  border: 1px dotted;
}
* {
  height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <element>test</element>
</div>
like image 108
Rahil Wazir Avatar answered Mar 06 '26 02:03

Rahil Wazir


The problem is that the $watch only gets called once something calls $apply() or $digest(). Angular won't run watchers for every event as that would make the browser really laggy. Put the run section in your main module.

angular.module('app', []).directive(...).run(function($rootScope) {
    angular.element(window).on("resize", function() {
        $rootScope.$apply();
    });
})
like image 30
Zenorbi Avatar answered Mar 06 '26 02:03

Zenorbi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!