Reputation: 5204
I'm trying to setup my app to watch the window.innerWidth
property and add a property to the $scope
based on that width. It works the first time, but not on any resize after that. Is the $digest method not being called? If so why not?
Module
//Initialize angular module include route dependencies
var app = angular.module("selfservice", ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl:"partials/login.html",
controller:"login"
});
});
Controller
app.controller("login", ['$scope', function ($scope) {
$scope.$watch(
function () {
return window.innerWidth;
},
function (newval, oldval) {
if (newval < 700) {
$scope.classExpand = 'expand';
} else {
$scope.classExpand = '';
}
console.log(newval, oldval);
});
}]);
View
<div class="small-12 column">
<a href="/portal" class="button radius large {{classExpand}}">Sign In</a>
</div>
This works the first time, if I refresh the screen after resizing it, the expand class is applied, but when I resize it, nothing happens, the console.log function doesn't even fire
Upvotes: 1
Views: 1207
Reputation: 9409
Resizing the window doesn't cause Angular to re-run a $digest
loop, so window.innerWidth
's value is checked only when something else causes it.
You should instead use a directive (ie. don't do this work in your controller), binding to the window.onresize
event:
.directive('watchResize', function(){
return {
restrict: 'A',
link: function(scope, elem, attr) {
angular.element(window).on('resize', function(){
scope.$apply(function(){
scope.classExpand = (window.innerWidth < 700) ? 'expand' : '';
});
});
}
}
});
In this case, you call scope.$apply
. This causes the $digest loop to run following this event, which is outside of the Angular context.
You can use this directive to decorate an element on the same scope as the variable you're changing:
<div watch-resize>
{{ classExpand }}
</div>
Demo (best viewed full-screen)
Upvotes: 2