Search code examples
angularjsresizeangular-directive

Define and Watch a variable according to windowidth


I'm struggling creating a directive to assign and update a variable, that compares to the window width, and updates with resize.

I need the variable as compared to using CSS because I will work it into ng-if. What am I doing wrong? Here is the code:

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

function AppController($scope) {}

app.directive('widthCheck', function ($window) {
    return function (scope, element, attr) {

        var w = angular.element($window);
        scope.$watch(function () {
            return {
                'w': window.innerWidth
            };
        }, function (newValue, oldValue, desktopPlus, isMobile) {
            scope.windowWidth = newValue.w;
            scope.desktopPlus = false;
            scope.isMobile = false;
            scope.widthCheck = function (windowWidth, desktopPlus) {
                if (windowWidth > 1399) {
               scope.desktopPlus = true;
              }
              else if (windowWidth < 769) {
                scope.isMobile = true;
              }
              else {
                scope.desktopPlus = false;
                scope.isMoblie = false;
              }
            }

        }, true);

        w.bind('resize', function () {
            scope.$apply();
        });
    }
}); 

JSfiddle here: http://jsfiddle.net/h8m4eaem/2/


Solution

  • As mentioned in this SO answer it's probably better to bind to the window resize event with-out watch. (Similar to Mr. Berg's answer.)

    Something like in the demo below or in this fiddle should work.

    var app = angular.module('miniapp', []);
    
    function AppController($scope) {}
    
    app.directive('widthCheck', function($window) {
      return function(scope, element, attr) {
        var width, detectFalse = {
          desktopPlus: false,
          isTablet: false,
          isMobile: false
        };
    
        scope.windowWidth = $window.innerWidth;
    
        checkSize(scope.windowWidth); // first run
    
        //scope.desktopPlus = false;
        //scope.isMoblie = false; // typo
        //scope.isTablet = false;
        //scope.isMobile = false;
    
        function resetDetection() {
          return angular.copy(detectFalse);
        }
    
        function checkSize(windowWidth) {
          scope.detection = resetDetection();
    
          if (windowWidth > 1000) { //1399) {
            scope.detection.desktopPlus = true;
          } else if (windowWidth > 600) {
            scope.detection.isTablet = true;
          } else {
            scope.detection.isMobile = true;
          }
        }
        angular.element($window).bind('resize', function() {
          width = $window.innerWidth;
          scope.windowWidth = width
    
          checkSize(width);
          // manuall $digest required as resize event
          // is outside of angular
          scope.$digest();
        });
      }
    });
    .fess {
      border: 1px solid red;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="miniapp" ng-controller="AppController">
    
      <div width-check class="fess" resize>
        window.width: {{windowWidth}}
        <br />desktop plus: {{detection.desktopPlus}}
        <br />mobile: {{detection.isMobile}}
        <br />tablet: {{detection.isTablet}}
        <br/>
      </div>
    </div>