Upon observation, it becomes clear that the object in question is immutable. The values of width
and height
are retrieved once during the creation of $scope.browser
. As these values remain constant and do not change, the callback function for $watch
will not be triggered.
To address this issue, there are a few possible solutions:
1) Instead of watching the object value, consider watching a function value like so:
$scope.$watch(function() {
return {
width: document.getElementById("area").offsetWidth,
height: document.getElementById("area").offsetHeight
}
}, function(newValue, oldValue) {
console.log("changed from: " + oldValue.width + " to " + newValue.width);
}, true);
While this method may be inefficient due to slow DOM access, it can be considered as an option if other remedies are not viable in your scenario.
2) Identify situations where #area
undergoes dimension changes. Is it due to browser resizing or external scripts like jQuery? For instance, to capture window resize events, you can implement the following directive:
.directive('windowResize',['$parse', '$timeout', function($parse, $timeout){
return function($scope, $element, $attrs) {
var fn = $parse($attrs.windowResize);
$(window).on('resize', function(){
$scope.$apply(function() {
fn($scope);
});
});
}])
//template
<div id="area" window-resize="onWindowResize()"></div>
If the dimension changes are caused by another script, you could obtain the scope from the DOM event or directly modify $scope.browser
like below:
//jquery script
var dimensions = {widht: newWidht, height: newHeight};
updateAreaDimensions(dimensions);
//broadcast event, decoupling this script from scope's code
$('body').scope().$broadcast('areaDimensionsUpdated', dimensions);
//or modify your $scope.browser object
$('body').scope().browser = dimensions;
If the changes are triggered by an event, you can listen for it within your scope:
$scope.$on('areaDimensionsUpdated', function($event, args) {
//
});