【问题标题】:Does $last mean that ng-repeat elements are already rendered?$last 是否意味着已经渲染了 ng-repeat 元素?
【发布时间】:2015-11-27 17:30:01
【问题描述】:

问题

if(scope.$last)
{
   //get container height
}

我一直认为这是获取容器高度的正确方法,该容器内部具有 ng-repeated 元素。我已经得出结论,这不是正确的方法。

看看我的指令:

AdminApp.directive("ngExpander", function($rootScope, $timeout){

var GetProperContainerHeight = function(container, content){

    var container = $(container);
    var content = $(content);

    container.height(content.outerHeight());

    return container.height();
}

return{
    restrict:'A',
    link:function(scope, elem, attr){

        if(scope.$last){

            $timeout(function(){

                $rootScope.ContainerHeight = GetProperContainerHeight(attr.container, attr.content);

            }, 500);

        }

    }
}

});

如果我没有添加 $timeout,该指令将无法正常工作,因为它不会返回正确的容器高度(我当时获得的一些负值)。

背景

指令在这里起作用:

<div class="SwitchContent" data-ng-show="ShowContent" id="testId">

    <div class="user-list-element"
                                data-ng-repeat="user in UserList | filter:userFilter track by $index"
                                data-ng-click="GetUserDetails(user);"
                                data-ng-expander
                                data-container="div.UserPanel"
                                data-content="div[id=testId]">

        <i class="fa fa-user fa-lg padding-r-10"></i> {{ user.name + ' ' + user.surname }}

    </div>

</div>

如何在没有 $timeout 的情况下获得正确的结果?

【问题讨论】:

    标签: javascript jquery angularjs


    【解决方案1】:

    你不能在没有超时的情况下做到这一点,因为 Angular 渲染是在你的指令编译后异步发生的。但你不需要的是一个你可能不喜欢的数字 500。

    只使用$timeout 不带第二个参数。

    $timeout(function(){
      $rootScope.ContainerHeight = SetProperContainerHeight(attr.container, attr.content);
    });
    

    这会将任务立即放入浏览器队列中。在浏览器停止渲染和超时开始之间,您仍然会有一些时间,但这是您可以做的最接近的时间。

    编辑

    问题可能出在您的scope.$last 方法中。除了if(scope.$last){,您可以做的是观看 HTML 内容:

    link:function(scope, elem, attr){
    
        scope.$watch(function() {
            return elem.html();
        }, function() {
            $timeout(function(){
    
                $rootScope.ContainerHeight = GetProperContainerHeight(attr.container, attr.content);
    
            });
        });
    
    }
    

    虽然它看起来很丑,但它总是对我有用。每当元素的 HTML 发生更改(只要ng-repeat 更改元素的内部内容),就会发生观察者事件。

    这里仍然需要超时,因为 HTML 已更改但尚未呈现,因此您需要将其放入异步浏览器队列并设置超时。

    这还有另一个优点:当前高度始终反映在您的 rootScope 属性中,而您的方法只会在指令加载时执行一次。

    【讨论】:

    • 请尝试第二种建议的方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-26
    • 2015-01-19
    • 2016-07-21
    • 1970-01-01
    • 2012-01-26
    相关资源
    最近更新 更多