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

时间:2014-08-03 20:25:41

标签: jquery angularjs

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

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

HTML:

<!DOCTYPE html>
<html ng-app="myApp">

    <head>
    <link rel="stylesheet" href="style.css">
    </head>

    <body ng-controller="myController">

        <p>Container height: {{containerHeight}}</p>

        <div id="container">
            <div class="box" ng-repeat="box in boxes">
                Box number: {{box}}
            </div>
        </div>

        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
        <script src="script.js"></script>
    </body>

</html>

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;
}

你可以view a demo of my problem on Plunker

5 个答案:

答案 0 :(得分:10)

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

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

  1. 实例化控制器并填充范围,触发角度$摘要,因此DOM更新
  2. 您计算的高度仍为零
  3. 摘要周期结束,DOM更新
  4. 通过在$ timeout内进行计算,您可以在上面的步骤3之后将其推送到调用堆栈的末尾并获得正确的高度

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

答案 1 :(得分:2)

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

有很多种方法,一种是通过添加自定义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

答案 2 :(得分:2)

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

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

用这个

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

答案 3 :(得分:1)

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

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

#container{
    display:inline-block;
}

#container{
    float:left;
}

希望有所帮助

答案 4 :(得分:0)

我相信,在实例化控制器时,容器没有内容,因此它的高度为零。 如果要获得高度,则必须在执行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)

}]);