Duncan Malashock
Duncan Malashock

Reputation: 786

Angular $watch isn't responding to window resize

I have an Angular app set up with a $watch on window.innerHeight and window.innerWidth to adjust an auto-truncate length variable. It works when I initially load or reload the page, but not on page resize. Can anyone help?

Here's my template:

<body class="partner_widget" ng-app="PartnerWidgetApp">
  <div id="description" ng-controller="PartnerWidgetController" ng-init="description='<%= expert_description %>'">
    {{ description_text | cut:true:blurb_truncate_length:'...' }}
  </div>
</body>

And here's my Angular code:

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

PartnerWidgetApp.controller('PartnerWidgetController', ['$scope',
    function($scope) {
        $scope.blurb_truncate_length = 180;

        $scope.$watch(function () {
            return $scope.description;
        }, function (result) {
            if (result) $scope.description_text = result;
        });

        $scope.$watch(function(){
           return window.innerWidth * window.innerHeight;
        }, function(value) {
           var the_width = window.innerWidth * 0.55;
           var the_height = window.innerHeight - 100;
           var text_area = Math.floor(the_width * the_height / (12*12) );
           $scope.blurb_truncate_length = text_area;
        });

    }
]);

angular.module('ng').filter('cut', function () {
    return function (value, wordwise, max, tail) {
        if (!value) return '';
        max = parseInt(max, 10);
        if (!max) return value;
        if (value.length <= max) return value;

        value = value.substr(0, max);
        if (wordwise) {
            var lastspace = value.lastIndexOf(' ');
            if (lastspace != -1) {
                value = value.substr(0, lastspace);
            }
        }
        return value + (tail || ' …');
    };
});

Upvotes: 1

Views: 322

Answers (1)

Kristiyan Kostadinov
Kristiyan Kostadinov

Reputation: 3712

Because technically you're trying to watch $scope.window, if you want to listen for changes in window size, use:

window.addEventListener('resize', function() {
    $scope.$apply(function(){ 
        $scope.blurb_truncate_length = 2 
    });
}, true);

You also need to use $scope.$apply in order to run a digest cycle and update the scope with the new value.

Better explanation by @Terry:

I was eluding to this in my comment. $apply() forces Angular to perform a digest cycle. When a value that is part of the Angular app changes, Angular knows about it and updates the UI. When a value exists outside of Angular's framework (window.something), Angular only knows about it when it runs a "check" (cycle), $apply() tells it to do this check.

And a link to the wiki: https://github.com/angular/angular.js/wiki/When-to-use-$scope.$apply()

Upvotes: 4

Related Questions