【问题标题】:AngularJS: set same height for divs in ng-repeatAngularJS:在 ng-repeat 中为 div 设置相同的高度
【发布时间】:2016-06-14 13:23:55
【问题描述】:

我是一个 AngularJS 新手,使用 Angular + Angular 移动 UI 在 phonegap 中开发应用程序。

我在 Bootstrap 列中的模板文件中有一个 div 列表不使用 jQuery。我需要在 Bootstrap 列中应用一个响应于其宽度的高度来平方 div。它应该是一个非常简单的脚本,但我无法处理。

这是我的模板:

template.html

<div ng-controller="ControllerIndex as Ctrl" item-list>    
    <div ng-repeat="item in items" >
        <div class="col-xs-4 object-list-container">
            <div class="object-list" >
                <p ng-bind-html="item.name"></p>
            </div>
        </div>
    </div>    
</div>

这是我的控制器

angular.module('app').controller('ControllerIndex', function ($scope, $http, $element) {
    $scope.items =[];

    $http.get(baseUrl +'data/item.json').success(function(data){
        $scope.items = data.item;
    }).error(function(){
        commonError();
    });

});

这里是我的指令

angular.module('app').directive('itemList', function($timeout){
    return {
        link: function ($scope, $element, $attrs) {
        //I tried a lot of things
        $timeout(function(){
                var elements = document.getElementsByClassName("object-list");
                console.log(elements); //Gives an array of 2
                var elementsLenght = elements.length;
                console.log(elementsLenght); //Gives 0!!!!!!
            });

             //Get the max height and set to the other div, but i can't enter this cycle
             for (var i = 0; i < elementsLenght; i++) {
                    var elementHeight = elements[i].offsetHeight;
                    //console.log(elementHeight);
                    if (elements[i].offsetHeight > maxHeight) {
                        maxHeight = elementHeight;
                    }
                }    


        //Attempt number 2
var angularElement = angular.element($element);
 var elementObject = angular.element($element[0].querySelector('.object-list'));
console.log(elementObject); //Gives a T object with lenght 0
            var xx =  angular.element(elementObject[0]);
            console.log(xx.offsetHeight);
            console.log('elementObject: ', angular.element(elementObject[0])); //Gives html       


       }
    }
});

我想我错过了一些东西。谢谢!

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    您可以使您的指令成为 ng-repeat 的一部分并检测 ng-repeat 何时完成加载,并且在该指令中,一旦您检测到最后一个已完成加载,请执行您的第一个尝试解决方案。

    模板:

    <div ng-controller="ControllerIndex as Ctrl">    
        <div ng-repeat="item in items" item-list>
            <div class="col-xs-4 object-list-container">
                <div class="object-list" >
                    <p ng-bind-html="item.name"></p>
                </div>
            </div>
        </div>    
    </div>
    

    指令:

    angular.module('app').directive('itemList', function($timeout){
        return {
            link: function ($scope, $element, $attrs) {
                 if ($scope.$last){
                     var elements = document.getElementsByClassName("object-list");
                     var maxHeight = 0;
                     //Get the max height and set to the other div
                     $timeout(function(){
                        for (var i = 0; i < elements.length; i++) {
                           var elementHeight = elements[i].offsetHeight;
                           //console.log(elementHeight);
                           if (elements[i].offsetHeight > maxHeight) {
                               maxHeight = elementHeight;
                           }
                        }    
                     });
                 }
            }
        }
    });
    

    【讨论】:

    • 感谢您的回答@Arathi Sreekumar。现在我得到了正确的elements.lenght,但是当我访问elements[i].offsetHeight 时我得到0,因为如果我console.log(elements[i]) 它打印html 而不是元素。你能解释一下为什么吗?谢谢!
    • elements[i] 是一个 html 元素。所以这是正确的。尝试打印元素[i].offsetHeight。如果它的打印为 0,那可能是因为它仍然没有在 dom 上渲染,不幸的是。如果不实际查看代码并尝试不同的东西,我不能说。
    • 是的,它正在打印 0。您需要查看更多内容吗?
    • 我需要一个示例 plunker/jsfiddle 才能说更多。您可以尝试在 for 循环周围添加超时。
    • 是的,成功了!您可以编辑您的答案以便我批准吗?谢谢!
    【解决方案2】:

    我与同样的问题斗争了很长时间。修改任何高度时,将 div 的高度绑定在一起。这是一个角度指令,直到今天都对我有帮助。

    var app = angular.module('app'); //insert your module name instead
    
    function bind_height() {
        function doforthiselem(me) {
            var value = $(me).attr("bind-height");
            var elems = $("[bind-height='" + value + "']");
            var heights = elems.toArray().map(function (elem) { return $(elem).height(); });
            if (Math.max.apply(me, heights) > Math.min.apply(me, heights)) $(me).height(Math.max.apply(me, heights));
        }
        $("[bind-height]").each(function () {
            doforthiselem(this);
        });
    }
    
    $(window).load(function () {
        if (typeof app == "undefined") bind_height();
    });
    
    app.directive("bindHeight", function () {
        return {
            restrict: 'A',
            link: function ($scope, element, attrs) {
                bind_height();
                element.bind("DOMSubtreeModified", function () {
                    bind_height();
                });
            }
        }
    });
    

    要使用,您需要将您希望将其高度绑定到相同值的元素的 [bind-height] 属性值设置为。例如,

    <div>
        <div bind-height="my-binding" style="height: 80px;">
            <p>Hello World</p>
        </div>
        <div bind-height="my-binding" style="height: 25px;">
            <p>Hello America</p>
            <p>Hello World</p>
        </div>
        <div bind-height="my-binding" style="height: 63px;">
            <p>Shoot for the stars</p>
        </div>
    </div>
    

    所有 [bind-height] 属性具有“my-binding”作为其值的 div 将其高度绑定到“最高”div 的高度。如果其中一个被修改,并且它的高度发生了变化,那么其他的也会被更新。

    在 ng-repeat 的情况下,这也很有效...

    <div ng-repeat="item in items" bind-height="item-height-bind">
        <!--do stuff-->
    </div>
    

    如果您的元素在每行三列中,您可以将它们绑定成三列...

    <div ng-repeat="item in items" bind-height="item-height-{{ceil(($index + 1)/3)}}">
        <!--do stuff-->
    </div>
    

    我希望这对你有帮助。

    【讨论】:

    • 不幸的是,这是一个基于 jQuery 的答案。我不想用jQuery,还是谢谢!
    • 真的吗?这是为什么呢?
    • 也许我错了,但 $ 是关于 jquery 命名空间的。我认为不支持 $(window).load() 没有 jquery 的加载方法。你能解释一下我应该如何使用它吗?
    • windows 加载功能仅在您不想使用 angular 的情况下才存在……您不妨将其删除。是的,jQuery 是必需的。我只是想知道为什么您需要不使用它。有了武士刀,为什么还要用小刀打僵尸?
    • 1) 尝试以正确的方式使用 Angular。 2)由于应用程序性能而避免使用jquery
    【解决方案3】:

    为了改进arathi-sreekumar 的答案,我对其进行了修改以获得完整的工作代码

    <div ng-controller="ControllerIndex as Ctrl">    
        <div ng-repeat="item in items" item-list="object-list">
            <div class="col-xs-4 object-list-container">
                <div class="object-list" >
                    <p ng-bind-html="item.name"></p>
                </div>
            </div>
        </div>    
    </div>
    

    现在一个指令获取一个 CSS 类作为参数并将元素的高度设置为最大高度

    let myDirective = 'itemList';
    angular.module('app').directive('itemList', function($timeout){
        return {
            link: function ($scope, $element, $attrs) {
                 if ($scope.$last){
                     var elements = document.getElementsByClassName($attrs[myDirective]);
                     var maxHeight = 0;
                     //Get the max height
                     $timeout(function(){
                        for (var i = 0; i < elements.length; i++) {
                           var elementHeight = elements[i].offsetHeight;
                           //console.log(elementHeight);
                           if (elements[i].offsetHeight > maxHeight) {
                               maxHeight = elementHeight;
                           }
                        }
                        // set to max height to divs
    
                        for (var j = 0; j < elements.length; j++) {
                            if (elements[j].offsetHeight < maxHeight) {
                                angular.element(elements[j]).height(maxHeight);
                                console.log(elements[j].offsetHeight);
                            }
                        }
    
    
                     });
                 }
            }
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2015-12-27
      • 2015-10-10
      • 2014-12-19
      • 1970-01-01
      • 2011-01-29
      • 2011-10-04
      • 2017-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多