gregwinn gregwinn - 3 months ago 15
AngularJS Question

Watch for screen size change in a directive Angularjs

I am having an issue with using

$watch
in a directive. I want to update an elements
left
and
top
based on some basic information on the page. Below is my code:



var myApp = angular.module("myApp", []);

var offset_x_function = function(){
return (($('.map').width() / 2) - ($('#map_display_img').width() / 2));
}
var offset_y_function = function(){
return (($('.map').height() / 2) - ($('#map_display_img').height() / 2));
}

myApp.directive("plotDevice", function($window){
offset_x = offset_x_function();
offset_y = offset_y_function();

return {
restrict: 'A',
link: function(scope, elem, attrs){
scope.$watch(function(){
return $window.innerWidth;
}, function(value) {
offset_y = offset_y_function();
offset_x = offset_x_function();
});
scope.$watch(function(){
return $window.innerHeight;
}, function(value) {
offset_y = offset_y_function();
offset_x = offset_x_function();
});
angular.element(elem).css("left", (parseInt(offset_x) + parseInt(attrs["x"])).toString() + "px" );
angular.element(elem).css("top", (parseInt(offset_y) + parseInt(attrs["y"])).toString() + "px" );
}
}
});

.map {
height: calc(100vh - 73px);
width: 100%;
}

.map img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div class="map">
<img id="map_display_img" src="some/image/path" width="1000" height="1000" />
<div plot-device data-x="100" data-y="200"><p>item over image</p></div>
</div>





While the directive works when the page loads: All
plot-device
elements get a style with a
left
and
top
. When the screen size is adjusted the style is not updated.

Answer

You are only setting offset_x and offset_y in the $watch callback. You are never actually updating the element except when the directive initializes.

You would need the angular.element(elem).css("left", ...) and angular.element(elem).css("top", ...) lines in the $watch callback. (Ideally you would have them in a function that gets called at initialization and in the $watch callbacks)

On a side note, there is a $window.on('resize', function(event){}) event you could listen for instead of using watchers.