Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the window width in angularJS on resize from a controller?

Tags:

angularjs

Ho can I get the window width in angularJS on resize from a controller? I want to be able to get it so I can display some div with <div ng-if="windowWidth > 320">

I can get the windowWidth on the initial page load but not on resize...

'use strict';

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

app.controller('mainController', ['$window', '$scope', function($window, $scope){
	var mainCtrl = this;
	mainCtrl.test = 'testing mainController';
  
    // Method suggested in @Baconbeastnz's answer  
    $(window).resize(function() {
      $scope.$apply(function() {
        $scope.windowWidth = $( window ).width();
      });
    });
  
    /* this produces the following error
    /* Uncaught TypeError: mainCtrl.$digest is not a function(…)
    angular.element($window).bind('resize', function(){
        mainCtrl.windowWidth  = $window.innerWidth;
        // manuall $digest required as resize event
        // is outside of angular
        mainCtrl.$digest();
    });  
    */
}]);

// Trying Directive method as suggested in @Yaser Adel Mehraban answer.
/*app.directive('myDirective', ['$window', function ($window) {
     return {
        link: link,
        restrict: 'E'            
     };
     function link(scope, element, attrs){
       angular.element($window).bind('resize', function(){
           scope.windowWidth = $window.innerWidth;
       });    
     }    
 }]);*/
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<body ng-app="app" ng-controller="mainController as mainCtrl">
	<p>{{mainCtrl.test}}</p>
	<hr />
    <p ng-if="windowWidth > 600">The window width is {{windowWidth}}</p>
    <div my-directive ng-if="windowWidth > 320">It works!</div>
</body>

I see in this answer they explain how you can get it from within a directive but how can you get it to work from within a controller?

like image 345
Holly Avatar asked Dec 15 '16 23:12

Holly


3 Answers

The best way is to use a directive and watch for resize event of the window:

'use strict';

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

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

     return {
        link: link,
        restrict: 'A'           
     };

     function link(scope, element, attrs){

       angular.element($window).bind('resize', function(){
           scope.windowWidth = $window.innerWidth;
       });    
     }    
 }]);

And use it on your div:

<div my-directive ng-if="windowWidth > 320">

Here is a working plunker.

like image 71
Yaser Avatar answered Nov 08 '22 13:11

Yaser


Finnally got it working with the below. Took most of the code from https://stackoverflow.com/a/23078185/1814446.

The only difference was for the ng-if to work the directive had to be put on a parent html element.

'use strict';

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

app.controller('mainController', ['$window', '$scope', function($window, $scope){
	var mainCtrl = this;
	mainCtrl.test = 'testing mainController';
}]);

app.directive('windowSize', function ($window) {
  return function (scope, element) {
    var w = angular.element($window);
    scope.getWindowDimensions = function () {
        return {
            'h': w.height(),
            'w': w.width()
        };
    };
    scope.$watch(scope.getWindowDimensions, function (newValue, oldValue) {
      scope.windowHeight = newValue.h;
      scope.windowWidth = newValue.w;
      scope.style = function () {
          return {
              'height': (newValue.h - 100) + 'px',
              'width': (newValue.w - 100) + 'px'
          };
      };
    }, true);

    w.bind('resize', function () {
        scope.$apply();
    });
  }
})
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<body window-size my-directive ng-app="app" ng-controller="mainController as mainCtrl">
  <p>{{mainCtrl.test}}</p>
  <hr />
  <div ng-if="windowWidth > 500">
    <h4 style="margin:5px 0">It works!</h4>
    <p style="margin:0">window.height: {{windowHeight}}</p>			     <p style="margin:0">window.width: {{windowWidth}}</p>			     <p style="margin:0">{{mainCtrl.test}}</p>
  </div>
</body>
like image 27
Holly Avatar answered Nov 08 '22 11:11

Holly


Getting the window width on resize isn't anything specific to Angular JS. in fact Angular doesn't provide any capability to do it. It's native javascript, the native window object fires a resize event that you can access. jQuery provides a handy wrapper for this. By using a simple callback in your controller and then updating your double bound windowWidth property on the $scope object you can get the functionality you need without using a directive.

$(window).resize(function() {
  $scope.windowWidth = $( window ).width();
});
like image 6
williamsandonz Avatar answered Nov 08 '22 13:11

williamsandonz