我是所有Angular World的新手,我正面临着管理指令的问题。
我正在开发一个使用Tabs的项目,我希望扩展其功能以处理溢出的标签,当窗口大小比我所有标签的宽度都窄时,所以我需要计算元素的某些维度来实现这一点。 选项卡是从$ scope中的Object构建的,问题是计算维度的指令是在完全编译视图之前运行的。
Plnkr链接: http://plnkr.co/edit/LOT4sZsNxnfmQ8zHymvw?p=preview
我尝试了什么:
我认为有一些AngularJs事件或属性来处理这种情况。
请帮助:)
答案 0 :(得分:8)
我在你的plunker上做了一个分支,我认为这就是你要找的东西
我将你的指令改为
.directive('onFinishRenderFilters', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attr) {
if (scope.$last === true) {
$timeout(function () {
scope.$emit('ngRepeatFinished');
});
}
}
}
});
然后在你的HTML上我添加了指令
<li ng-repeat="tab in tabs" on-finish-render-filters>
我把最后一件事放在重复完成后我想要运行的代码
$scope.$on('ngRepeatFinished', function (ngRepeatFinished) {
$scope.tabs = [{
index: 1,
title: "Tab 1",
link: "/tab1/"
},{
index: 2,
title: "Tab 2",
link: "/tab2/"
},{
index: 3,
title: "Tab 3",
link: "/tab3/"
},{
index: 4,
title: "Tab 4",
link: "/tab4/"
}];
});
答案 1 :(得分:6)
对于ng-repeat中使用的指令,AngularJS似乎没有可靠的渲染后回调。 [1]
也许您可以通过为特定屏幕宽度添加“响应式”溢出控制元素来在CSS级别上解决此问题。
更新:现在有一种方法可以使用嵌套的$ timeouts来完成此操作。请参阅:http://lorenzmerdian.blogspot.de/2013/03/how-to-handle-dom-updates-in-angularjs.html
答案 2 :(得分:5)
您可以在实际DOM元素上添加监视,以便了解ng-repeat何时加载到DOM中。
给你的ul一个id,比如#tabs
$scope.$watch(
function () { return document.getElementById('tabs').innerHTML },
function(newval, oldval){
//console.log(newval, oldval);
//do what you like
}, true);
答案 3 :(得分:3)
根据您的评论,您已经有了一个有效的解决方案......而且它目前是我所知道的唯一解决方案:$ timeout。
问题是,你想达到什么目标?完成所有渲染后,您需要回调。好的,好的,但棱角分明怎么知道这个?在使用角度显然正在开发的现代应用程序中,重新渲染可能一直发生!即使在初始化应用程序之后,也会在从后端加载数据的情况下发生js事件,从而导致重新渲染。用户的鼠标移动可以触发元素的重新渲染,由于CSS规则,这些元素甚至在角度范围之外。任何时候,都可能发生重新渲染。
那么,通过这些考虑,angularJS在渲染完成时会告诉您什么?它只能告诉您,当前处理当前的$ apply和/或$ digest链时,浏览器事件队列现在是空的。确切地说,这是angularJS知道的唯一信息。你使用$ timeout,延迟为0。
是的,你是对的,在一个更大的应用中,这可能是棘手的,以至于它不再可靠。但在这种情况下,您应该考虑如何以另一种方式解决这个问题。 F.i.如果稍后发生重新渲染,则必须有一个原因,例如从后端加载的新数据。如果是这样,您知道何时加载数据并因此发生重新渲染,因此您确切知道何时需要更新宽度。