在指令上设置超时,用于测量具有ng-cloak的div的高度

时间:2016-01-30 18:22:20

标签: angularjs

当我设置测量div高度的指令时,我开始体验页面加载时的预测行为。

使用该指令,我获得了div的高度,用于手风琴目的动画,当打开时。如果我没有在div上设置max-height,那么动画就不起作用了。在模板中,它看起来像这样:

<div class="accordion-wrapper" ng-class="{ 'hidden': ! showProductInfo }" log-height style="max-height: {{readyHeight}}px;">

测量的div有闪烁效果,所以我将ng-cloak添加到该div。有了它,当页面加载时,它还会加载该特定指令的css属性display:none !imporant

所以在这种情况下,我用来获取高度的代码总是返回空白响应,因为那个css属性。

衡量高度的当前代码

<script type="text/javascript">
var rootApp = angular.module('rootApp', ['ngMaterial','ngAnimate']);

rootApp.directive('logHeight', function($timeout) {
    return {
        restrict: 'A',
        link: function(scope, element) {
            scope.Math = window.Math;
            scope.notReadyHeight = element.prop('offsetHeight');
            scope.value = 0;
            scope.readyHeight = scope.Math.min(scope.value + scope.notReadyHeight);
        }
    };
});
</script>

现在,我想在渲染html模板后触发此指令。我不会安静地理解如何将$timeout实现到此指令中,这将起作用。

2 个答案:

答案 0 :(得分:0)

您可以使用$timeout来延迟执行代码,直到浏览器呈现div:

$timeout(function()
{            
    scope.notReadyHeight = element.prop('offsetHeight');
    scope.value = 0;
    scope.readyHeight = scope.Math.min(scope.value + scope.notReadyHeight);
}, 200);

200ms延迟可能更大或更小,具体取决于浏览器渲染延迟。但200ms应该可以工作。

但是我无法理解你在这个指令中要做什么。

顺便说一下,

scope.readyHeight = scope.Math.min(scope.value + scope.notReadyHeight);

相当于

scope.readyHeight = scope.value + scope.notReadyHeight;

答案 1 :(得分:0)

link功能中包含超时:

rootApp.directive('logHeight', function($timeout) {
    return {
        restrict: 'A',
        link: function(scope, element) {
            scope.Math = window.Math;
            scope.notReadyHeight = element.prop('offsetHeight');
            scope.value = 0;
            $timeout(function() {
                scope.readyHeight = scope.value + scope.notReadyHeight;
            }, 0);
        }
    };
});

请注意,$timeout很有用,因为即使延迟时间为0毫秒,它也会等待摘要循环完成,因此任何大小调整,渲染,ng-cloak等等都应该由它运行的时间。

另请注意,您要小心依赖注入。如果你缩小上面的代码,它可能会破坏。你应该使用这种风格:

rootApp.directive('logHeight', ['$timeout', function($timeout) {
    // code goes here
}]);