$last是否意味着已经渲染了ng个重复元素

Does $last mean that ng-repeat elements are already rendered?

本文关键字:ng 元素 是否 last 意味着      更新时间:2023-09-26

问题

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

我一直在想,这是获得容器高度的正确方法,容器内有ng个重复的元素。我得出的结论是,这不是一个恰当的方法。

看看我的指令:

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,我如何才能获得正确的结果?

您不能在没有超时的情况下执行此操作,因为在编译指令后会异步进行角度渲染。但你不需要的是一个你可能不喜欢的数字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属性中,而方法在指令加载时只会执行一次。