if(scope.$last)
{
//get container height
}
我一直在想这是获得容器高度的正确方法,其内部有重复元素。我得出的结论是,这不是正确的方法。
看看我的指示:
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 ,我怎样才能获得正确的结果?
答案 0 :(得分:0)
如果没有超时,则无法执行此操作,因为角度渲染在编译指令后异步发生。但是你不需要的是你可能不喜欢的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属性中,而您的方法只会在指令加载时执行一次。