51

I have revealing module pattern which looks like this:

'use strict';

angular.module('app', [])
   .directive('myDirective', ['SomeDep', function (SomeDep) {
       var linker = function (scope, element, attr) {
          // some work
       };

       return {
          link: linker,
          restrict: 'E'
       };
   }])
;

What I'm having trouble with is integrating a $watch into this. Specifically watching for window resize, with the '$window' service.

[EDIT]:

I realised what my issue was this whole time... I was restricting to element, when I forgot that I was implementing it as an attribute... @_@;

isherwood
  • 58,414
  • 16
  • 114
  • 157
Lightfooted
  • 799
  • 1
  • 6
  • 13
  • If you've found a solution that's not offered below, provide and accept an answer so this post can be resolved. Don't answer a question in the question itself. – isherwood Jun 20 '16 at 19:36

3 Answers3

94

You shouldn't need a $watch. Just bind to resize event on window:

DEMO

'use strict';

var app = angular.module('plunker', []);

app.directive('myDirective', ['$window', function ($window) {

     return {
        link: link,
        restrict: 'E',
        template: '<div>window size: {{width}}px</div>'
     };

     function link(scope, element, attrs){

       scope.width = $window.innerWidth;

       angular.element($window).bind('resize', function(){

         scope.width = $window.innerWidth;

         // manuall $digest required as resize event
         // is outside of angular
         scope.$digest();
       });

     }

 }]);
Matt Herbstritt
  • 4,754
  • 4
  • 25
  • 31
  • 12
    and what if that directive is no longer in use on the page? just have the event callback fired needlessly for the rest of time for every directive element that ever existed. Go to to a page with this directive one hundred times and have the event processed one hundred times regardless of which template is currently displaying... – user3338098 May 10 '16 at 19:02
  • 8
    If you want to take care of cleaning up when the directive is not in use, implement $destroy on the directive. http://stackoverflow.com/questions/23031381/how-to-safely-clean-up-angularjs-event-binding-in-a-directive – David Salamon Aug 09 '16 at 14:45
  • Your simplicity is much appreciated. – R Claven Apr 12 '17 at 18:34
41

You can listen resize event and fire where some dimension change

directive

(function() {
'use strict';

    angular
    .module('myApp.directives')
    .directive('resize', ['$window', function ($window) {
        return {
            link: link,
            restrict: 'A'
        };

        function link(scope, element, attrs){
            scope.width = $window.innerWidth;
            function onResize(){
                // uncomment for only fire when $window.innerWidth change   
                // if (scope.width !== $window.innerWidth)
                {
                    scope.width = $window.innerWidth;
                    scope.$digest();
                }
            };

            function cleanUp() {
                angular.element($window).off('resize', onResize);
            }

            angular.element($window).on('resize', onResize);
            scope.$on('$destroy', cleanUp);
        }
    }]);
})();

In html

<div class="row" resize> ,
    <div class="col-sm-2 col-xs-6" ng-repeat="v in tag.vod"> 
        <h4 ng-bind="::v.known_as"></h4>
    </div> 
</div> 

Controller :

$scope.$watch('width', function(old, newv){
     console.log(old, newv);
 })
Simon D
  • 4,150
  • 5
  • 39
  • 47
nguyên
  • 5,156
  • 5
  • 43
  • 45
  • 3
    this is lacking a call to unbind and will most likely create zombie listeners, e.g. when navigating to a different view inside the app. – dube Jun 08 '16 at 12:18
1

// Following is angular 2.0 directive for window re size that adjust scroll bar for give element as per your tag

---- angular 2.0 window resize directive.
import { Directive, ElementRef} from 'angular2/core';

@Directive({
       selector: '[resize]',
       host: { '(window:resize)': 'onResize()' } // Window resize listener
})

export class AutoResize {

element: ElementRef; // Element that associated to attribute.
$window: any;
       constructor(_element: ElementRef) {

         this.element = _element;
         // Get instance of DOM window.
         this.$window = angular.element(window);

         this.onResize();

    }

    // Adjust height of element.
    onResize() {
         $(this.element.nativeElement).css('height', (this.$window.height() - 163) + 'px');
   }
}
Nikhil Tambave
  • 155
  • 2
  • 9