使用ng-repeat指令的容器高度为零

我有一个带有ng-repeat指令的div,它通过一个数组并将一堆div添加到我的容器中。 当我在容器上调用.height()时,它现在用div填充,它返回0.它似乎在执行ng-repeat指令之前返回高度。 在将ng-repeat指令中的所有元素添加到DOM后,如何检索高度?

我有以下HTML,JS和CSS代码:

HTML:

       

Container height: {{containerHeight}}

Box number: {{box}}

JS:

 var myApp = angular.module('myApp', []); myApp.controller('myController', ['$scope', function($scope) { $scope.boxes = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; $scope.containerHeight = $('#container').height(); }]); 

CSS:

 .box { width: 200px; height: 200px; padding: 10px; background-color: skyblue; margin: 5px; } 

您可以在Plunker上查看我的问题演示 。

http://plnkr.co/edit/g4DfdiKX4HO3qW8kVmsF?p=preview

问题是在呈现DOM之前计算高度,因为DOM呈现是异步的。 否则,您的线程将在DOM呈现时被阻止,并且您的页面将被冻结,直到昂贵的DOM操作完成。 这是事情发生的顺序……

  1. 实例化控制器并填充范围,触发角度$摘要,从而触发DOM更新
  2. 你计算高度,它仍然是零
  3. 摘要周期结束,DOM更新

通过在$ timeout内进行计算,您可以在上面的步骤3之后将其推送到调用堆栈的末尾并获得正确的高度

 $timeout(function () { // calculate height }); 

好的发现了关于plunker的问题。 替换它

 $scope.containerHeight = $('#container').height(); 

有了这个

  setTimeout(function(){ $scope.containerHeight = $('#container').height() $scope.$apply(); }, 0); 

问题是当容器的高度获得新值时,需要通知角度同步周期(摘要)。

有很多方法,一个是通过添加一个自定义directive如下面的内容,它将为您提供DOM元素的引用,您可以添加一个自定义watch来检查高度和没有jquery

指示

 myApp.directive('heightBind', function() { return { scope: { heightValue: '=' }, link: function($scope, $element) { $scope.$watch(function() { $scope.heightValue = $element.height(); }); } } }) 

用法

 < ... height-bind height-value="containerHeight"> 

http://plnkr.co/edit/XQB7MTP9fyXdir2EOopM?p=preview

Div不会自动拉伸以包含其子元素。 你必须做他们称之为’clearfix’的黑客,将父div设置为“display:inline-block;”,或浮动父div。 只是谷歌“clearfix”div,你会发现一些类将修复div来拉伸它的高度以包含它的孩子。 在这种情况下,您可以执行以下任何操作:

 #container:after { content: ""; display: table; clear: both; } 

要么

 #container{ display:inline-block; } 

要么

 #container{ float:left; } 

希望有所帮助

我相信,在实例化控制器时,容器没有内容,因此它的高度为零。 如果要获得高度,则必须在执行ng-repeat后设置范围高度。 一种方法是使用超时。 这不是一个很好的解决方案,但确实说明了这个问题。 超时将在ng-repeat执行后执行。

 var myApp = angular.module('myApp', []); myApp.controller('myController', ['$scope', '$timeout', function($scope, $timeout) { $scope.boxes = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; $timeout( function(){ $scope.containerHeight = $('#container').height(); },100) }]);