2
votes

I created a directive which makes elements resize automatically according to percents of window. But there are still problems I can't solve.

Here are the files:

autoresize.js:

angular.module('autoresize', [])

    .directive('autoresize', function() { return {

        scope:{theId:'@id', theClass:'@class', wFactor:'@w', hFactor:'@h'},
        link: function(scope, elem, attrs) {

            scope.onResize = function() {
                if(scope.hFactor != 'w')
                {
                    scope.height = Math.floor($(window).innerHeight()*scope.hFactor);
                }
                if(scope.wFactor != 'h')
                {
                    scope.width = Math.floor($(window).innerWidth()*scope.wFactor);
                }
                if(scope.hFactor == 'w')
                {
                    scope.height = scope.width;
                }
                if(scope.wFactor == 'h')
                {
                    scope.width = scope.height;
                }

                $(elem).outerHeight(scope.height);
                $(elem).outerWidth(scope.width);
            }
            scope.onResize();

            angular.element($(window)).bind('resize', function() {
                scope.onResize();
            });
        }
    }
});

test.htm:

<!DOCTYPE html>
<html>

    <head>
        <title>Test</title>
        <style type="text/css">
*
{
    box-sizing: border-box;
}

html, body
{
    margin: 0;
    padding: 0;
}

#left, #right
{
    display: inline-block;
}

#left
{
    background: #101010;
}

#right
{
    background: #777777;
}

#bottom
{
    background: #AAAAAA;
}
        </style>
    </head>

    <body>

        <div ng-app="testApp" ng-controller="testCtrl">
            <div id="content">
                <div id="left" autoresize w="0.5" h="0.8"></div><div id="right" autoresize w="0.5" h="0.8"></div>
                <div id="bottom" autoresize w="1" h="0.2">{{width}}</div>
            </div>

        </div>

        <script src="vendor/angular.min.js"></script>
        <script src="vendor/jquery-2.1.3.min.js"></script>

        <script src="autoresize.js"></script>
        <script>
angular.module('testApp', ['autoresize'])

    .controller('testCtrl', function($scope, $http) {



});
        </script>

    </body>
</html>

The first problem is that when I open the webapp, the sizes don't init correctly: I must resize the window to get it work. Why doesn't the line scope.onResize() in the link function init everything correctly?

The second problem is that the scope variables "width" and "height" are not accessible in the element: in the example below, there isn't anything in the div "bottom". How do you get them accessible?

(Here you could think that CSS would be sufficient, however actually my app is a bit more complicated that the example below and CSS isn't sufficient)

Thanks a lot!

2
For the second problem, the isolated scope was the culprit. - Nicolas K.

2 Answers

0
votes

You need call you scope.onResize(); method from load event of element, That would be efficient to initial kick off for setting css of elements

Add below method in directive & remove direct call of scope.onResize(); from link function

Code

 element.on('load', function() {
     scope.onResize();
 });
0
votes

Ad 1)
The scope.onResize() does not work, because when the link function on a directive is called, the DOM element handled by that directive is not yet rendered (it will be, once the directive is done processing). Try to wrap that call in $timeout(), like this:

$timeout(function() { scope.onResize(); });

This will cause calling scope.onResize() during the next tick, which is after the directive finishes processing.

Ad 2)
See this question, on how to modify scope from within a directive.