AngularJs:View完全呈现后运行指令

时间:2013-03-04 08:39:09

标签: angularjs angularjs-directive

我是所有Angular World的新手,我正面临着管理指令的问题。

我正在开发一个使用Tabs的项目,我希望扩展其功能以处理溢出的标签,当窗口大小比我所有标签的宽度都窄时,所以我需要计算元素的某些维度来实现这一点。 选项卡是从$ scope中的Object构建的,问题是计算维度的指令是在完全编译视图之前运行的。

Plnkr链接: http://plnkr.co/edit/LOT4sZsNxnfmQ8zHymvw?p=preview

我尝试了什么:

  1. 使用templateUrl
  2. 在指令中加载模板
  3. 使用transclude
  4. 在ng-repeat中使用$ last
  5. 尝试重新排序指令并在每个选项卡中创建一个虚拟指令以触发事件
  6. 我认为有一些AngularJs事件或属性来处理这种情况。

    请帮助:)

4 个答案:

答案 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/"
        }];

  });

http://plnkr.co/edit/TGduPB8FV47QvjjLnFg2?p=preview

答案 1 :(得分:6)

对于ng-repeat中使用的指令,AngularJS似乎没有可靠的渲染后回调。 [1]

也许您可以通过为特定屏幕宽度添加“响应式”溢出控制元素来在CSS级别上解决此问题。

  1. https://groups.google.com/forum/#!topic/angular/SCc45uVhTt8
  2. 更新:现在有一种方法可以使用嵌套的$ 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.如果稍后发生重新渲染,则必须有一个原因,例如从后端加载的新数据。如果是这样,您知道何时加载数据并因此发生重新渲染,因此您确切知道何时需要更新宽度。

相关问题