Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS directive watch parent size change

Problem

I have a simple directive that executes sizing updates on a particular element. This watches the window size and makes adjustments accordingly.

MyApp.directive('resizeTest', ['$window', function($window) {
  return {
    restrict: 'AC',
    link: function(scope, element) {
      var w = angular.element($window);
      scope.$watch(function() {
        return { 'h': w.height(), 'w': w.width() };
      }, function(newValue, oldValue) {
        // resizing happens here
      }, true);
      w.bind('resize', function() { scope.$apply(); });
    }
  };
}]);

This works just fine.

It just so happens that inside of the div tag that is associated with, I have a child div. When the parent is resized, I want to make positioning alterations on the child element. However, I cannot get the trigger to fire.

This gets called at startup, but does not get triggered when the element is resized or the window changes:

MyApp.directive('centerVertical', ['$window', function($window) {
  return {
    restrict: 'AC',
    link: function(scope, element) {
      element.css({border: '1px solid #0000FF'});
      scope.$watch('data.overlaytype', function() {
        $window.setTimeout(function() {
          console.log('I am:      ' + element.width() + 'x' + element.height());
          console.log('Parent is: ' + element.parent().width() + 'x' + element.parent().height());
        }, 1);
      });
    }
  };
}]);

What type of binding or watch configuration should I be using to check for resizing of the parent element?

Fiddle

https://jsfiddle.net/rcy63v7t/1/

like image 300
el n00b Avatar asked Mar 27 '15 14:03

el n00b


1 Answers

The value data.overlaytype you are observing in the centerVertical directive is not on the scope so the resulting value is undefined and this value never changes that's why you dont get the listener executed. To check if the size of the parent element changed you can check it in the $watch function like this:

scope.$watch(
    function () { 
        return {
           width: element.parent().width(),
           height: element.parent().height(),
        }
   },
   function () {}, //listener 
   true //deep watch
);

Moreover remember, when you want to use an already existing module you can't call it like this angular.module('myModule', []) because this mean creating new module. You have to just pass the module name angular.module('myModule'), which is second thing why your code didn't work.

like image 188
jcz Avatar answered Sep 28 '22 09:09

jcz